【问题标题】:Intercept Unity 2.0 HandlerAttribute without an interface在没有接口的情况下拦截 Unity 2.0 HandlerAttribute
【发布时间】:2010-09-04 01:18:25
【问题描述】:

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

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] 属性。我已经看过很多关于如何配置拦截设置的示例,例如:

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

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

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

干杯。 贾斯。

【问题讨论】:

    标签: unity-container aop


    【解决方案1】:

    很遗憾,您不会让它在带有 Unity 拦截的 ASP.NET 页面中工作。

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

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

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

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

    我希望在某个地方有一个钩子可以自定义 ASP.NET 如何创建对象 - BuildManager 可能吗?但我对细节知之甚少,而且我认为这需要一些相当严重的黑客攻击才能工作。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-17
      • 1970-01-01
      • 1970-01-01
      • 2017-06-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多