c# AOP自定义属性统一
本文关键字:自定义属性 AOP | 更新日期: 2023-09-27 18:10:43
我试图开发一个自定义属性来装饰方法,当我这样做时,我希望它们被属性"捕获",因此它决定如何处理异常。
我知道有两种方法可以做到这一点:——PostSharp- Enterprise Library Unity
我想避免第一个,我想继续使用Unity,因为我们已经使用了企业库。
因此,为了使它工作,我做了以下操作:
我的调用处理程序:
public class LoggingCallHandler : ICallHandler
{
public bool Rethrow
{
get; set;
}
public bool Log
{
get; set;
}
public int Order
{
get; set;
}
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
var result = getNext().Invoke(input, getNext);
if (result.Exception != null)
{
if (this.Rethrow)
throw result.Exception;
if (this.Log)
this.LogException(result.Exception);
}
return result;
}
private void LogException(Exception ex)
{
// Do stuff
}
}
自定义属性
public class LoggingCallHandlerAttribute : HandlerAttribute
{
private bool rethrow;
private bool log;
public LoggingCallHandlerAttribute(bool rethrow, bool log = false)
{
this.rethrow = rethrow;
this.log = log;
}
public override ICallHandler CreateHandler(IUnityContainer container)
{
return new LoggingCallHandler() { Rethrow = this.rethrow, Log = this.log };
}
}
我的类,方法用属性
装饰 public class TestManager
{
[LoggingCallHandler(false, false)]
public void DoStuff()
{
throw new Exception("TEST");
}
}
当我运行这个方法时,没有AOP发生。
我知道Unity可能依赖或完全依赖于容器。但我们目前没有使用任何这些,所以我们只想用[LoggingCallHandler]属性装饰一个功能,仅此而已。
如果容器确实是必要的,可以考虑,但最好有一个适合所有用途的容器(至少现在…)。
这有可能实现吗?
谢谢大家
我积极致力于NConcern . net AOP框架——一个新的开源项目。你可以试着做你需要做的事。
管理异常处理的方面
public class ExceptionHandlingAspect : IAspect
{
private void Log(Exception exception)
{
//...
}
public IEnumerable<IAdvice> Advise(MethodInfo method)
{
//advise only if method is tagged.
if (Attribute.IsDefined(method, typeof(LoggingCallHandlerAttribute))
{
//get attribute
var attribute = method.GetCustomAttributes(typeof(LoggingCallHandlerAttribue))[0] as LoggingCallHandlerAttribute;
//describe how yo rewrite method.
yield return Advice.Basic.Arround(invoke =>
{
try { invoke(); } //call original code
catch (Exception e)
{
if (attribute.Rethrow)
{
throw;
}
if (attribute.Log)
{
this.Log(e);
}
}
});
}
}
}
为LoggingCallHandlerAttribute属性的所有方法附加aspect;
Aspect.Weave<ExceptionHandlingAspect>(method => method.IsDefined(typeof(LoggingCallHandlerAttribute), true);
如果你不使用Unity容器来构造你的对象,那么拦截(通过ICallHandler)将不起作用。
当你通过Unity DI容器创建对象时,这种拦截依赖于Unity来包装它们。
即使你不使用DI容器,PostSharp拦截也会起作用。
如果您不使用DI容器,(在我看来)最好还是保持原样,不要在代码库中引入DI容器。请看我的文章。
你可能还想考虑使用DynamicProxy进行拦截。但是这需要您在创建对象时手动包装它们。