当前有一个特性类
[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 3年前