在没有接口的情况下拦截 Unity 2.0 HandlerAttribute [英] Intercept Unity 2.0 HandlerAttribute without an interface

查看:26
本文介绍了在没有接口的情况下拦截 Unity 2.0 HandlerAttribute的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm a first-time user of the AOP features of Unity 2.0 and would like some advice. My goal is to be able to log method calls in an ASPX page, like so:

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

        [Log]
        private void Testing()
        {

        }
    }

这是LogAttribute的代码:

public class LogAttribute : HandlerAttribute
{
    public override ICallHandler CreateHandler(IUnityContainer container)
    {
        return new LogHandler(Order);
    }
}

现在是 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; }
}

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

The problem I have is how to use the [Log] attribute. I've seen plenty of example of how to configure the interception settings, for example:

container.AddNewExtension<Interception>();
container.Configure<Interception>().SetDefaultInterceptorFor<ILogger>(new InterfaceInterceptor());

但这意味着我有一个接口可以拦截,而我没有.我有使用 [Log] 属性的 ASPX 页面.

But this implies that I have an interface to intercept, which I don't. I have the ASPX page which uses the [Log] attribute.

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

so how can I configure Unity to make use of the [Log] attribute? I've done this before using PostSharp and would like to be able to use Unity to do the same.

干杯.杰斯.

推荐答案

很遗憾,您将无法在使用 Unity 拦截的 ASP.NET 页面中使用它.

You're unfortunately not going to get this to work in an ASP.NET page with Unity interception.

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

Unity interception uses a runtime interception model. Depending on the interceptor you choose, you'll either get a subclass with virtual method overrides to call the call handlers (VirtualMethodInterceptor) or a separate proxy object (Interface or TransparentProxyInterceptor) which execute the call handlers and then forward to the real object.

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

Here's the issue - ASP.NET controls creation and calls to your page, and there's no easy way to hook into them. Without controlling the creation of the page object, you can't use the VirtualMethodInterceptor, because that requires that you instantiate a subclass. And you can't use the proxy version either, because you need ASP.NET to make calls through the proxy.

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

PostSharp gets around this because it's actually rewriting your IL at compile time.

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

Assuming you could hook into the creation of the page object, you'd have to use the VirtualMethodInterceptor here. It's a private method, so you want logging on "self" calls (calls from one method of the object into another method on the same object). The proxy-based interceptors can't see those, since the proxy is a separate instance.

我希望某处有一个钩子可以自定义 ASP.NET 创建对象的方式 - BuildManager 可能?但我对细节了解得还不够多,我预计这需要一些非常认真的黑客才能开始工作.

I expect there is a hook somewhere to customize how ASP.NET creates object - BuildManager maybe? But I don't know enough about the details, and I expect it'll require some pretty serious hacking to get work.

那么,你如何解决这个问题?我的建议(实际上,无论如何我都建议这样做)是对您的 ASP.NET 页面使用模型-视图-演示者模式.使页面对象本身变得愚蠢.它所做的只是将调用转发到一个单独的对象 Presenter.Presenter 是真正的逻辑所在,它独立于 ASP.NET 的细节.您在可测试性方面获得了巨大收益,并且您可以拦截对演示者的调用,而不会遇到 ASP.NET 给您带来的所有困难.

So, how do you get around this? My recommendation (actually, I'd recommend this anyway) is to use the Model-View-Presenter pattern for your ASP.NET pages. Make the page object itself dumb. All it does is forward calls to a separate object, the Presenter. The Presenter is where your real logic is, and is independent of the details of ASP.NET. You get a huge gain in testability, and you can intercept calls on the presenter without all the difficulty that ASP.NET gives you.

这篇关于在没有接口的情况下拦截 Unity 2.0 HandlerAttribute的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆