単一のアプリケーションを使用するソリューションの場合、一般的なアドバイスは、コンテナーをアプリケーション プロジェクト (Web アプリまたは Web サービス プロジェクト) に登録することです。Web アプリケーションの場合、これは通常 Global.asax になりますApplication_Start
。すべてを結び付けるこの場所は、DI 用語ではコンポジション ルートと呼ばれます。
マルチアプリケーション ソリューションの場合でも、アプリケーション プロジェクトごとに 1 つのコンポジション ルートが存在します。すべてのアプリケーションには独自の構成があるため、これは必須です。一方、重複したコードは常に悪いものです。新しい抽象化を導入するときに、3 つの場所を変更する必要はありません。
秘訣は、すべての登録をプロジェクト階層の下に移動することです。たとえば、ビジネス層アセンブリ (およびその下) に依存する単一の「ブートストラップ アセンブリ」を定義し、変更されないアセンブリのすべての登録を保持できます。その後、アプリケーションのコンポジション ルートは、そのアセンブリを使用して既定の登録を取得し、アプリケーション固有の依存関係でそれを拡張できます。
そのようなことは次のようになります。
// MVC Composition root
public static void Bootstrap()
{
var container = new Container();
// Default registrations
BusinessLayerBootstrapper.Bootstrap(container);
// Application specific registrations
container.Bind<IUserContext>().To<AspNetUserContext>();
DependencyResolver.Current =
new ContainerDependencyResolver(container);
}
// Windows Service Composition root
public static void Bootstrap()
{
var container = new Container();
// Default registrations
BusinessLayerBootstrapper.Bootstrap(container);
// Application specific registrations
container.Bind<IUserContext>().To<SystemUserContext>()
.SingleScoped();
// Store somewhere.
Bootstrapper.Container = container;
}
// In the BL bootstrap assembly
public static class BusinessLayerBootstrapper
{
public static void Bootstrap(Container container)
{
container.Bind<IDepenency>().To<RealThing>();
// etc
}
}
別のブートストラップ アセンブリを用意する必要はありませんが (このコードを BL 自体に配置できます)、これにより、ビジネス レイヤー アセンブリをコンテナーへの依存関係から解放することができます。
Bootstrap()
また、(Ninject) モジュールを使用する代わりに、静的メソッドを呼び出しているだけであることにも注意してください。あなたの質問は一般的であり、アドバイスはすべてのDIフレームワークで同じであるため、フレームワークから独立した回答を維持しようとしました。ただし、もちろん、必要に応じて Ninject モジュール機能を使用できます。