2016-08-08 10 views
-1

私は最終的にIoCやその他のパタ​​ーンについて学習するプロセスに没頭しており、アセンブリのリストに基づいてオープンジェネリックスを登録しようとすると問題に遭遇しました。フレームワークのコアを別のクラスライブラリに構築し、フレームワークから継承するいくつかのテストクラスを宣言する一連のテストプロジェクトを用意しています。シンプルなインジェクタとアセンブリスキャン

問題は、ICommandHandler<>オープンジェネリックが何も見つけられないように、実行時にAddPersonCommandHandler : ICommandHandler<AddPersonCommand>がロードされないframework.test.service dllです。 AddPersonCommandHandlerインスタンスを事前に作成してから、リストに追加アセンブリを1つ作成してから動作させる必要があります。

ロードを強制する簡単な方法はありますか?

=========== 編集: これは、アプリケーションドメインと他のアセンブリへの参照を保持するユニットテストプロジェクトのワイヤーアップコードです。

public Container SetupIoc() 
{ 
    var container = new Container(); 

    container.Register(typeof(IUnitOfWork), typeof(EntityFrameworkUnitOfWork), Lifestyle.Singleton); 

    var assemblies = AppDomain.CurrentDomain.GetAssemblies(); 

    container.Register(typeof(ICommandHandler<>), assemblies); 


    container.Verify(); 

    return container; 
} 

IUnitOfWork

はDatabase.Interface.dll である ICommandHandler<>はTest.Service.dllであるCore.dll AddPersonCommandHandlerである - 一緒に真の解決策を置く模倣プロジェクトの設定アップ構造のスイートの一部と参照ユニットテストによって。

UnitOfWorkを直接指定しているので、ユニットまたは作業登録が正常に機能しているというのは、ICommandHandlerインターフェイスが正常にバインドされているコアにあるのに対して、直接起こります。 Post Verify()私はcontainerに仕事単位の登録のみを表示します。 Test.Service.dllの読み込みを取得するには、AddPersonCommandHandlerが表示されます。をTestInitメソッドでインスタンス化できます。

プロジェクトのすべてのDLLを手動でロードする必要があるのはちょっと気になるようです。また、DLLの実行フォルダをスキャンすると、すでに読み込まれているものもあります...読み込みがうまくいくか、既にロードされているかどうか調べるために慎重にチェックする必要がありますか?

+2

使用しているフレームワークによっては、型を明示的に登録/ロードするためのテキストベースの設定が可能です。あるいは、Assembly.Load()で手動で行うこともできます(アセンブリ参照を追加しても、 )。今私は、しかし、私は完全に質問を理解するか分からない。 – Lucero

+0

私は他の決議を見てきましたので、研究を行っています。私が知りたかったのは、アセンブリをスキャンしてロードする必要があったかどうかでした。 –

+0

登録を行い、どのプラットフォームが使用されているか、mvc、wpf、windowsサービスなどを示すコードを表示できますか? –

答えて

2

アセンブリがロードされていることを確認するために、AddPersonCommandHandlerというインスタンスを明示的に作成する必要はありません。 AppDomain.CurrentDomain.GetAssemblies()を呼び出す前に実行する静的なコードでアセンブリの型(AddPersonCommandHandlerなど)を参照するだけです。例:

// Load BL assembly 
Type type = typeof(AddPersonCommandHandler); 

container.Register(typeof(ICommandHandler<>), AppDomain.CurrentDomain.GetAssemblies()); 

この参照をComposition Rootに保存することをお勧めします。これにより、コンテナの初期化(App_startまたは統合テスト)に関係なく、同じアセンブリがロードされます。

より明示的な方法は、登録のために使用されるべきアセンブリの明示的なリストを作ることです。

// Adding the (redundant) namespace of the type makes it very clear to the 
// user if this type is still located in the business layer. 
Assembly[] businessLayerAssemblies = new[] { 
    typeof(MyComp.MyApp.BusinessLayer.AddPersonCommandHandler).Assembly 
} 

container.Register(typeof(ICommandHandler<>), businessLayerAssemblies); 
container.Register(typeof(IQueryHandler<,>), businessLayerAssemblies); 
container.Register(typeof(IEventHandler<>), businessLayerAssemblies); 
container.Register(typeof(IValidator<>), businessLayerAssemblies); 

これは有用なタイプが含まれていることはありませんアセンブリの大部分をスキャン防ぐので、私は、後者のアプローチを好みます、アセンブリを非常に明示的に表現しています(アセンブリの読み込みを行う型を暗黙的に参照するのではなく)。

+0

クールメイト。それが仕事ではなく、むしろ私はそれを単純なアプローチだと思う必要はありません。私はあなたの時間を感謝します。 –

+0

@StephenYorkまた、[this](https://stackoverflow.com/a/12781486/264697)を行うこともできます。 – Steven

+0

うん、私はそれを避け、元の返信でオプションBを愛することを望んでいた。再度、感謝します。 –

関連する問題