当前有一个特性类
[AttributeUsage(AttributeTargets.All)]
//[AttributeUsage(System.AttributeTargets.All, AllowMultiple = false, Inherited = true)]
public class CompensableAttribute : Attribute
{
public int Retries { get; set; }
    public string CompensationMethod { get; set; }
    public int RetryDelayInMilliseconds { get; set; }
    public int Timeout { get; set; }
    private readonly ILogger _logger = LogManager.GetLogger(typeof(SagaStartAttribute));
    private readonly IEventAwareInterceptor _compensableInterceptor;
    private readonly OmegaContext _omegaContext;
    private readonly IRecoveryPolicy _recoveryPolicy;
    private readonly CompensationContext _compensationContext;
    private readonly IMessageSerializer _messageFormat;
    private readonly string _parenttxId;
    protected object InitInstance;
    protected MethodBase InitMethod;
    protected Object[] Args;
    public CompensableAttribute()
    {
    }
    public void Init(object instance, MethodBase method, object[] args)
    {
        InitMethod = method;
        InitInstance = instance;
        Args = args;
    }
    public CompensableAttribute(string compensationMethod, int retryDelayInMilliseconds = 0, int timeout = 0, int retries = 0)
    {
        _omegaContext = (OmegaContext)ServiceLocator.Current.GetInstance(typeof(OmegaContext));
        _compensableInterceptor = (IEventAwareInterceptor)ServiceLocator.Current.GetInstance(typeof(IEventAwareInterceptor));
        _recoveryPolicy = (IRecoveryPolicy)ServiceLocator.Current.GetInstance(typeof(IRecoveryPolicy));
        _compensationContext =
            (CompensationContext)ServiceLocator.Current.GetInstance(typeof(CompensationContext));
        _messageFormat = (IMessageSerializer)ServiceLocator.Current.GetInstance(typeof(IMessageSerializer));
        Retries = retries;
        CompensationMethod = compensationMethod;
        RetryDelayInMilliseconds = retryDelayInMilliseconds;
        Timeout = timeout;
        _parenttxId = _omegaContext.GetGlobalTxId();
    }
    public void OnEntry()
    {
        var type = InitInstance.GetType();
        _compensationContext.
            AddCompensationContext
            (type.GetMethod(CompensationMethod, BindingFlags.Instance | BindingFlags.NonPublic), type, InitInstance);
        _omegaContext.NewLocalTxId();
        var paramBytes = _messageFormat.Serialize(Args);
        _logger.Debug($"Initialized context {_omegaContext} before execution of method {InitMethod.Name}");
        _recoveryPolicy.BeforeApply(_compensableInterceptor, _omegaContext, _parenttxId, Retries, Timeout, CompensationMethod, paramBytes);
    }
    public  void OnExit()
    {
        _recoveryPolicy.AfterApply(_compensableInterceptor, _parenttxId, CompensationMethod);
        _logger.Debug($"Transaction with context {_omegaContext} has finished.");
    }
    public  void OnException(Exception exception)
    {
        _logger.Error($"Transaction {_omegaContext.GetGlobalTxId()} failed.", exception);
        _recoveryPolicy.ErrorApply(_compensableInterceptor, _parenttxId, CompensationMethod, exception);
    }
    public void OnAuthorization(AuthorizationFilterContext context)
    {
        throw new NotImplementedException();
    }
}
然后有个方法标识了这个特性
[Compensable(nameof(CancelTestNet))]
public void TestNet(int id)
{
throw new ArgumentException("test CancelTestSaga serivice error");
}
    void CancelTestNet(int id)
    {
        Console.WriteLine("测试CancelTestSaga");
        //_bookings.TryGetValue(booking.Id, out var carBooking);
        //carBooking?.Cancel();
    }
奇怪的是 这个方法执行了 但是标识特性 永远不执行 断点不会进入特性的构造函数中
建议改进一下排版,支持 markdown 语法
– dudu 4年前