コマンド ハンドラーの装飾に関するこの記事を読んだ後、今日は興味深い話題に乗り出しました。SimpleInjectorの代わりに Unity を使用してパターンを実装できるかどうかを確認したかったのですが、これまでのところ非常に難しいことがわかっています。
最初にやらなければならなかったことは、 UnityAutoRegistrationをインストールして、開いている汎用ICommandHandler<TCommand>
インターフェイスを解決することでした。その側面に対する現在の解決策は次のとおりです。
Container = new UnityContainer().LoadConfiguration();
Container.ConfigureAutoRegistration()
.ExcludeSystemAssemblies()
.Include(type => type.ImplementsOpenGeneric(typeof(ICommandHandler<>)),
(t, c) => c.RegisterType(typeof(ICommandHandler<>), t)
)
.ApplyAutoRegistration()
;
これは最初の部分で機能し、単一の ICommandHandler<TCommand>
. これまでのところイライラすることが証明されているのは、装飾ハンドラーの実装です。デコレーターとして1 秒追加するとすぐにICommandHandler<TCommand>
、Unity は StackOverflowException をスローします。Unity の内部についてはよくわかりませんが、どちらのインスタンスもICommandHandler<TCommand>
インターフェイスを実装しているため、どちらのインスタンス (コマンド ハンドラーまたはコマンド ハンドラー デコレーター) に解決するかを判断できないためだと推測しています。
グーグルで調べたところ、最初にこの記事にたどり着きました。これは、私がブルートフォースメソッドと見なす方法でそれを行う方法を説明しています. これらの 関連 ページも見つけましたが、どれも私の問題に対する完全な解決策ではありません (そして、私は無知すぎて自分でそれを理解できません)。
その後、同じ懸念に対処しているように見えるこの記事を見つけました。ただし、beefy のソリューションでは、オープン ジェネリックの処理が考慮されていません。現在、ほとんどの依存関係は .config ファイルの unity セクションから読み込まれているため、ハンドラーやデコレーターごとに大量のコンパイル済みコードを書きたくありません。ある種の UnityContainerExtension と DecoratorBuildStrategy を使用するのが正しい方法のようですが、わかりません。私はビーフィーのコードでしばらく遊んでいて、完全に立ち往生しています。ジェネリックを考慮して彼のコードを変更しようとすると、BadImageFormatExceptions が発生しました (正しくない形式のプログラムを読み込もうとしました (HRESULT からの例外: 0x8007000B))。
デコレーター チェーンを実装するためにこれを行うというアイデアが気に入っています。これは短く、懸念ごとに 1 行しかないからです。
var container = new Container();
// Go look in all assemblies and register all implementations
// of ICommandHandler<T> by their closed interface:
container.RegisterManyForOpenGeneric(typeof(ICommandHandler<>),
AppDomain.CurrentDomain.GetAssemblies());
// Decorate each returned ICommandHandler<T> object with an
// TransactionCommandHandlerDecorator<T>.
container.RegisterDecorator(typeof(ICommandHandler<>),
typeof(TransactionCommandHandlerDecorator<>));
// Decorate each returned ICommandHandler<T> object with an
// DeadlockRetryCommandHandlerDecorator<T>.
container.RegisterDecorator(typeof(ICommandHandler<>),
typeof(DeadlockRetryCommandHandlerDecorator<>));
...しかし、必要がなければ、コンテナーを Unity から Simple Injector に変更したくありません。
だから私の質問は、ユニティ(プラス)を使用してオープンジェネリックデコレータチェーンを実装するにはどうすればよいUnityAutoRegistration
ですか?