编程语言
首页 > 编程语言> > C#-Unity拦截GetCustomAttribute

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