在此先感谢您的帮助!(是的,底部有一个问题)
我正在使用 Unity 3.x 拦截来执行 AOP 前后数据库连接和事务活动。数据库拦截器总是被实例化,事务拦截器是基于 CustomAttributeMatchingRule 的,两者都通过 InterfaceInterceptor。我在我的 TransactionAttribute 中设置了一些属性:
[Transaction(IsolationLevel.ReadUncommitted, NoRollbackFor = new[] { typeof(TestException) })]
作为我在单元测试中使用的示例。我想在我的 TransactionCallHandler 类调用方法中访问它们。我看过例子说
var transactionAttribute = input.MethodBase.GetCustomAttribute<TransactionAttribute>(false);
是访问它的方式,但我的交易变量为空。我的结论是正在检查拦截代理类的自定义属性,而不是原始的具体实例。
我的解决方法是一直反映到类级别,深入了解被拦截的正确方法是什么,然后从那里执行获取自定义属性。
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);