团结拦截GetCustomAttribute [英] Unity Interception GetCustomAttribute

查看:235
本文介绍了团结拦截GetCustomAttribute的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在此先感谢您的帮助! (是的,有在底部是一个问题)



我使用Unity 3.x的拦截进行AOP前置和后置数据库连接和事务活动。数据库拦截器总是既可以通过InterfaceInterceptor实例化,事务拦截器是基于CustomAttributeMatchingRule。我有一个在我的TransactionAttribute被设置属性:



<预类=郎-CS prettyprint-覆盖> [交易(IsolationLevel.ReadUncommitted,NoRollbackFor =新[] {typeof运算(TestException)})]

作为一个例子,我用我的单元测试。我想访问他们在我TransactionCallHandler类的invoke方法。我见过的例子说



<预类=郎-CS prettyprint-覆盖> VAR transactionAttribute = input.MethodBase.GetCustomAttribute< TransactionAttribute>(假);



是访问此方式,但我的交易var为空。
我的结论是拦截代理类正在检查自定义属性,而不是原来的具体实例。



我的工作围绕这是反映所有方式回到一流水平,挖通找出正确的方法是,是被截获什么,并执行获取自定义从那里属性。



<预类=郎-CS prettyprint -override> VAR方法=输入
.TARGET
.GetType()
.GetMethods()
。凡(M = GT; m.Name == input.MethodBase.Name)
。凡(M = GT; m.GetCustomAttribute< TransactionAttribute>(假)!= NULL);



(有大约另一个代码30行,以确保如果我没有访问了错误的方法名方法有重载,因此业绩拖累...)



所以,在这一切之后,我的问题是:
我我没有正确地履行反射? ?
是有一个团结的错误,我应该报告



下面是我的容器定义:



<预类= 郎咸平-CS prettyprint-覆盖> 集装箱=新UnityContainer();
Container.AddNewExtension<&截取GT;();

Container.RegisterType< IMockUseDefaultConnectionString,MockUseDefaultConnectionString>(
新InterceptionBehavior< PolicyInjectionBehavior>(),
新型拦截< InterfaceInterceptor>(),
新InjectionConstructor(新DatabaseSettings ()));

Container.RegisterType< IMockUseHardcodedConnectionString,MockUseHardCodedConnectionString>(
新InterceptionBehavior< PolicyInjectionBehavior>(),
新型拦截< InterfaceInterceptor>(),
新InjectionConstructor(新DatabaseSettings
{
的ConnectionString = MockUseHardCodedConnectionString.ConnectionString
}));
/ * IDatabaseSettings未注册手动控制设置使用* /

VAR第一=新InjectionProperty(订单,1);
变种秒=新InjectionProperty(订单,2);

集装箱
.Configure<拦截>()
.AddPolicy(DatabaseConnectionPolicy)
.AddMatchingRule< NamespaceMatchingRule>(新InjectionConstructor(myNameSpace对象*​​。真))
.AddCallHandler< DatabaseConnectionCallHandler>(第一);

集装箱
.Configure<拦截>()
.AddPolicy(TransactionPolicy)
.AddMatchingRule(新CustomAttributeMatchingRule(typeof运算(TransactionAttribute),继承:FALSE) )
.AddCallHandler< TransactionCallHandler>(二);


解决方案

我认为你所看到的行为的后果截取的设计方法。当使用代理对象被创建一个InterfaceInterceptor实现但是目标接口的代理对象是从原始类型完全不同类型



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


Thanks in advance for your help! (Yes, there's a question at the bottom)

I'm using Unity 3.x Interception to perform AOP pre and post database connection and transaction activities. The database interceptor is always instantiated and the transaction interceptor is CustomAttributeMatchingRule based, both via InterfaceInterceptor. I have properties that are being set in my TransactionAttribute:

[Transaction(IsolationLevel.ReadUncommitted, NoRollbackFor = new[] { typeof(TestException) })]

as an example I'm using in my unit test. I would like to access them in my TransactionCallHandler class invoke method. I've seen examples saying

var transactionAttribute = input.MethodBase.GetCustomAttribute<TransactionAttribute>(false);

is the way to access this, yet my transaction var is null. My conclusion is the interception proxy class is being checked for the custom attribute and not the original concrete instance.

My work around for this is to reflect all the way back to the class level, dig through to figure out what the correct method is that's being intercepted and perform the get custom attribute from there.

var methods = input
  .Target
  .GetType()
  .GetMethods()
  .Where(m => m.Name == input.MethodBase.Name)
  .Where(m => m.GetCustomAttribute<TransactionAttribute>(false) != null);

(There's about another 30 lines of code to ensure I'm not accessing the wrong method name if the method has overloads; hence the performance drag...)

So, after all that, my question is: Am I not performing the reflection correctly? Is there a bug in Unity I should report?

Here's my container definitions:

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);

解决方案

I think the behavior you are seeing is a consequence of the design of the interception methods. When using an InterfaceInterceptor a proxy object is created that implements the target interface however the proxy object is a totally different type from the original type.

If you go with a VirtualMethodInterceptor, which is type compatible, then you should be able to get the custom attribute using your original approach. Of course, the downside of the VirtualMethodInterceptor is that all methods to intercept must be virtual.

这篇关于团结拦截GetCustomAttribute的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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