C# Unity拦截GetCustomAttribute

C# Unity拦截GetCustomAttribute,c#,unity-container,interception,getcustomattributes,C#,Unity Container,Interception,Getcustomattributes,提前感谢您的帮助!(是的,底部有一个问题) 我使用Unity3.x拦截来执行AOP前后的数据库连接和事务活动。数据库拦截器始终是实例化的,而事务拦截器是基于CustomAttributeMatchingRule的,两者都是通过InterfaceInterceptor实现的。我有在TransactionAttribute中设置的属性: [事务(IsolationLevel.ReadUncommitted,norollboor=new[]{typeof(TestException)}] 作为我在单

提前感谢您的帮助!(是的,底部有一个问题)

我使用Unity3.x拦截来执行AOP前后的数据库连接和事务活动。数据库拦截器始终是实例化的,而事务拦截器是基于CustomAttributeMatchingRule的,两者都是通过InterfaceInterceptor实现的。我有在TransactionAttribute中设置的属性:

[事务(IsolationLevel.ReadUncommitted,norollboor=new[]{typeof(TestException)}]
作为我在单元测试中使用的一个例子。我想在TransactionCallHandler类调用方法中访问它们。我见过这样的例子

var transactionAttribute=input.MethodBase.GetCustomAttribute(false);
是访问此的方法,但我的事务变量为null。 我的结论是,正在检查侦听代理类的自定义属性,而不是原始的具体实例

我在这方面的工作是一直反射到类级别,深入了解被截取的正确方法是什么,并从那里执行get custom属性

var方法=输入
.目标
.GetType()
.GetMethods()
.Where(m=>m.Name==input.MethodBase.Name)
。其中(m=>m.GetCustomAttribute(false)!=null);
(如果方法有重载,还有大约30行代码可以确保我没有访问错误的方法名称;因此性能会受到影响…)

因此,在所有这些之后,我的问题是: 我是否没有正确执行反射? 我应该报告Unity中有缺陷吗

以下是我的容器定义:

Container=newunitycontainer();
Container.AddNewExtension();
Container.RegisterType(
新的侦听行为(),
新的拦截器(),
新的InjectionConstructor(新的DatabaseSettings());
Container.RegisterType(
新的侦听行为(),
新的拦截器(),
新建InjectionConstructor(新数据库设置
{
ConnectionString=MockUseHardCodedConnectionString.ConnectionString
}));
/*未注册IDatabaseSettings以手动控制正在使用的设置*/
var first=新注入属性(“顺序”,1);
var second=新注入属性(“顺序”,2);
容器
.Configure()
.AddPolicy(“数据库连接策略”)
.AddMatchingRule(新注入构造函数(“MyNamespace.*,true))
.AddCallHandler(第一个);
容器
.Configure()
.AddPolicy(“交易策略”)
.AddMatchingRule(新的CustomAttributeMatchingRule(typeof(TransactionAttribute),继承:false))
.AddCallHandler(第二);

我认为您看到的行为是拦截方法设计的结果。当使用InterfaceInterceptor时,会创建一个代理对象来实现目标接口,但是代理对象的类型与原始类型完全不同


如果使用与类型兼容的VirtualMethodInterceptor,那么应该能够使用原始方法获取自定义属性。当然,VirtualMethodInterceptor的缺点是所有拦截方法都必须是虚拟的。

另一个选项是从HandlerAttribute创建子类。有关详细信息,请参阅此,或阅读。在HandlerAttribute的CreateHandler()实现中,将属性实例传递给调用处理程序实例,这样就不必调用GetCustomAttributes()。或者,在一个类中同时实现HandlerAttribute和ICallHandler,并只返回以下内容:

public sealed class AuditAttribute : HandlerAttribute, ICallHandler
{
    #region attribute properties
    public string Key { get; set; } // your own attribute properties

    public override ICallHandler CreateHandler(Microsoft.Practices.Unity.IUnityContainer container)
    {
        return this;
    }

    #endregion

    #region ICallHandler
    public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
    {
        // do stuff ...

        // then
        return getNext()(input, getNext);
    }

    public int Order { get; set; }
    #endregion

}

我浏览了一些示例代码,发现了一些我没有想到的非常简单的东西


当调用处理程序由属性创建时,将所需的参数传递到处理程序的构造函数中。然后它们位于用于属性的处理程序实例中。问题解决。

我同意@Tuzo对虚拟拦截的缩减。我不想在常规代码库中引入约定,我必须教给每一个新开发人员;更不用说在我离开这份合同后希望他们记得当初为什么要这么做了。我将向Unity interception项目添加一个请求,并查看是否可以将其纳入路线图。我对该项目的请求已通过以下方式结束:用户gmelnik已更新问题:Unity interception GetCustomAttribute。状态已从“建议”更改为“已关闭”,并有以下注释:“StackOverflow上提供的答案。”很好。我没有想到要这么做,它很好地解决了问题。但是,如果我想让多个属性一起工作,比如缓存(cacheResult、InvalidateCacheResult、CacheTimeout等),那么仍然需要执行令人讨厌的反射检查。您能提供少量代码来支持这一点吗?谢谢