首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在没有接口的情况下拦截Unity2.0 HandlerAttribute

在没有接口的情况下拦截Unity2.0 HandlerAttribute
EN

Stack Overflow用户
提问于 2010-09-02 19:39:28
回答 1查看 2.5K关注 0票数 2

我是第一次使用Unity 2.0的AOP特性,我想要一些建议。我的目标是能够在ASPX页面中记录方法调用,如下所示:

代码语言:javascript
复制
public partial class Page2 : Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
        }

        [Log]
        private void Testing()
        {

        }
    }

下面是LogAttribute的代码

代码语言:javascript
复制
public class LogAttribute : HandlerAttribute
{
    public override ICallHandler CreateHandler(IUnityContainer container)
    {
        return new LogHandler(Order);
    }
}

现在是LogHandler

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

代码语言:javascript
复制
container.AddNewExtension<Interception>();
container.Configure<Interception>().SetDefaultInterceptorFor<ILogger>(new InterfaceInterceptor());

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

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

干杯。雅斯。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2010-09-04 01:18:25

不幸的是,你不能让它在一个带有Unity interception的ASP.NET页面中工作。

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

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

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

假设您可以挂接到页面对象的创建过程中,那么在这里您必须使用VirtualMethodInterceptor。它是一个私有方法,所以你需要记录"self“调用(从对象的一个方法调用到同一对象上的另一个方法)。基于代理的拦截器看不到这些,因为代理是一个单独的实例。

我希望有一个钩子来定制ASP.NET创建对象的方式--也许是BuildManager?但我对细节了解得还不够多,我预计需要一些相当严重的黑客才能找到工作。

那么,你是如何解决这个问题的呢?我的建议(实际上,我还是推荐这样做)是对您的ASP.NET页面使用模型-视图-展示器模式。使页面对象本身成为哑巴。它所做的就是将调用转发到一个单独的对象,即Presenter。Presenter是您真正的逻辑所在,并且独立于ASP.NET的细节。您可以在可测试性方面获得巨大的收益,并且您可以拦截presenter上的调用,而不会像ASP.NET给您带来的所有困难。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3626711

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档