C#-Unity拦截GetCustomAttribute
作者:互联网
在此先感谢您的帮助! (是的,底部有一个问题)
我正在使用Unity 3.x Interception执行AOP之前和之后的数据库连接和事务活动.总是通过InterfaceInterceptor实例化数据库拦截器,事务拦截器基于CustomAttributeMatchingRule.我有在TransactionAttribute中设置的属性:
[Transaction(IsolationLevel.ReadUncommitted, NoRollbackFor = new[] { typeof(TestException) })]
以我在单元测试中使用的示例为例.我想在我的TransactionCallHandler类invoke方法中访问它们.我看过一些例子说
var transactionAttribute = input.MethodBase.GetCustomAttribute<TransactionAttribute>(false);
是访问此文件的方法,但我的交易var为null.
我的结论是,正在检查拦截代理类的自定义属性,而不是原始的具体实例.
为此,我的工作是一直追溯到类级别,进行深入挖掘以找出正在被拦截的正确方法,然后从那里执行get custom属性.
var methods = input
.Target
.GetType()
.GetMethods()
.Where(m => m.Name == input.MethodBase.Name)
.Where(m => m.GetCustomAttribute<TransactionAttribute>(false) != null);
(还有大约30行代码,以确保如果该方法有重载,我不会访问错误的方法名称;因此会拖累性能……)
所以,毕竟,我的问题是:
我没有正确执行反射吗?
我应该报告Unity中的错误吗?
这是我的容器定义:
Container = new UnityContainer();
Container.AddNewExtension<Interception>();
Container.RegisterType<IMockUseDefaultConnectionString, MockUseDefaultConnectionString>(
new InterceptionBehavior<PolicyInjectionBehavior>(),
new Interceptor<InterfaceInterceptor>(),
new InjectionConstructor(new DatabaseSettings()));
Container.RegisterType<IMockUseHardcodedConnectionString, MockUseHardCodedConnectionString>(
new InterceptionBehavior<PolicyInjectionBehavior>(),
new Interceptor<InterfaceInterceptor>(),
new InjectionConstructor(new DatabaseSettings
{
ConnectionString = MockUseHardCodedConnectionString.ConnectionString
}));
/* IDatabaseSettings is not registered to manually control the settings being used */
var first = new InjectionProperty("Order", 1);
var second = new InjectionProperty("Order", 2);
Container
.Configure<Interception>()
.AddPolicy("DatabaseConnectionPolicy")
.AddMatchingRule<NamespaceMatchingRule>(new InjectionConstructor("MyNamespace.*", true))
.AddCallHandler<DatabaseConnectionCallHandler>(first);
Container
.Configure<Interception>()
.AddPolicy("TransactionPolicy")
.AddMatchingRule(new CustomAttributeMatchingRule(typeof(TransactionAttribute), inherited: false))
.AddCallHandler<TransactionCallHandler>(second);
解决方法:
我认为您看到的行为是拦截方法设计的结果.使用InterfaceInterceptor时,会创建一个实现目标接口的代理对象,但是该代理对象与原始类型完全不同.
如果使用类型兼容的VirtualMethodInterceptor,则应该能够使用原始方法获得自定义属性.当然,VirtualMethodInterceptor的缺点是所有拦截方法都必须是虚拟的.
标签:unity-container,interception,c,getcustomattributes 来源: https://codeday.me/bug/20191123/2065295.html