拦截没有接口的Unity 2.0 HandlerAttribute

Jas*_*ans 2 aop unity-container

我是Unity 2.0的AOP功能的第一次使用者,并希望得到一些建议.我的目标是能够在ASPX页面中记录方法调用,如下所示:

public partial class Page2 : Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
        }

        [Log]
        private void Testing()
        {

        }
    }
Run Code Online (Sandbox Code Playgroud)

这是以下代码LogAttribute:

public class LogAttribute : HandlerAttribute
{
    public override ICallHandler CreateHandler(IUnityContainer container)
    {
        return new LogHandler(Order);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在LogHandler:

public class LogHandler : ICallHandler
{
    public LogHandler(int order)
    {
        Order = order;
    }

    public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
    {
        string className = input.MethodBase.DeclaringType.Name;
        string methodName = input.MethodBase.Name;

        string preMethodMessage = string.Format("{0}.{1}", className, methodName);
        System.Diagnostics.Debug.WriteLine(preMethodMessage); 

        return getNext()(input, getNext);
    }

    public int Order { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是如何使用该[Log]属性.我已经看到了很多关于如何配置拦截设置的示例,例如:

container.AddNewExtension<Interception>();
container.Configure<Interception>().SetDefaultInterceptorFor<ILogger>(new InterfaceInterceptor());
Run Code Online (Sandbox Code Playgroud)

但这意味着我有一个拦截界面,我没有.我有使用该[Log]属性的ASPX页面.

那么如何配置Unity来使用[Log]属性呢?我在使用PostSharp之前已经这样做了,并且希望能够使用Unity来做同样的事情.

干杯.雅.

Chr*_*res 6

遗憾的是,你不会在Unity拦截的ASP.NET页面中使用它.

Unity拦截使用运行时拦截模型.根据您选择的拦截器,您将获得一个带有虚方法覆盖的子类来调用调用处理程序(VirtualMethodInterceptor)或一个单独的代理对象(Interface或TransparentProxyInterceptor),它们执行调用处理程序然后转发到真实对象.

这是问题 - ASP.NET控制创建和调用页面,并没有简单的方法来挂钩它们.如果不控制页面对象的创建,则不能使用VirtualMethodInterceptor,因为这需要您实例化一个子类.并且您也不能使用代理版本,因为您需要ASP.NET通过代理进行调用.

PostSharp可以解决这个问题,因为它实际上是在编译时重写你的IL.

假设你可以挂钩创建页面对象,你必须在这里使用VirtualMethodInterceptor.它是一个私有方法,因此您希望登录"自"调用(从对象的一个​​方法调用到同一对象上的另一个方法).基于代理的拦截器无法看到这些,因为代理是一个单独的实例.

我希望有一个钩子来定制ASP.NET如何创建对象 - 可能是BuildManager?但我对细节知之甚少,而且我认为需要一些非常严重的黑客来获取工作.

那么,你怎么解决这个问题呢?我的建议(实际上,无论如何我都建议这样做)是为你的ASP.NET页面使用Model-View-Presenter模式.使页面对象本身变得愚蠢.它所做的只是前向调用单独的对象,即Presenter.Presenter是您真实逻辑的所在,并且与ASP.NET的细节无关.您可以获得可测试性方面的巨大收益,并且您可以在没有ASP.NET提供的所有困难的情况下拦截演示者上的调用.