よろしくお願いします。(はい、一番下に質問があります)
Unity 3.x Interception を使用して、AOP 前後のデータベース接続とトランザクション アクティビティを実行しています。データベース インターセプターは常にインスタンス化され、トランザクション インターセプターは CustomAttributeMatchingRule ベースであり、両方とも InterfaceInterceptor を介して行われます。TransactionAttribute に設定されているプロパティがあります。
[Transaction(IsolationLevel.ReadUncommitted, NoRollbackFor = new[] { typeof(TestException) })]
単体テストで使用している例として。TransactionCallHandler クラスの呼び出しメソッドでそれらにアクセスしたいと思います。私は言っている例を見てきました
var transactionAttribute = input.MethodBase.GetCustomAttribute<TransactionAttribute>(false);
これにアクセスする方法ですが、私のトランザクション変数は null です。私の結論は、元の具体的なインスタンスではなく、カスタム属性についてインターセプト プロキシ クラスがチェックされているということです。
これに対する私の回避策は、クラスレベルまでさかのぼって反映し、掘り下げてインターセプトされている正しいメソッドが何であるかを突き止め、そこからカスタム属性の取得を実行することです。
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);