リクエストごとにバインディングを交換できることを気にしません。しかし、できることは条件付きバインディングを使用することです。
例-デフォルトのバインディング:
protected override Ninject.IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<IAuthorizationService>()
.To<AuthorizationService>()
.InRequestScope();
kernel.Bind<IService>()
.To<BasicService>();
return kernel;
}
一部の基本ユーザーとVIPユーザーにIService
(必要な場所に)注入します。BasicService
ExtraService
条件付きバインディングのさまざまな方法の詳細については、「Ninject-コンテキストバインディング」を参照してください。
編集
条件付きバインディングは引き続き使用できると思います。IKernel
新しいdllからコンポーネントを登録する場所にを伝播するだけで済みます。たとえば、global.asax
dllモジュールを動的にロードするためにこれを持っています-アプリの起動時に実行されます。
モジュールのロード:
private void LoadAssemblies(IKernel kernel) {
foreach (var fileName in Directory.GetFiles(Server.MapPath("~/App_Data"), "*.dll")) {
Assembly loadedAssembly = Assembly.LoadFile(fileName);
try {
var moduleRegistrations = loadedAssembly.GetTypes()
.Where(t => t.IsClass && t.IsAbstract == false && typeof (IMyModuleRegistration).IsAssignableFrom(t));
foreach (var moduleRegType in moduleRegistrations ) {
IMyModuleRegistration moduleReg = (IMyModuleRegistration) Activator.CreateInstance(moduleRegType);
moduleReg.RegisterComponents(kernel);
}
}
catch (ReflectionTypeLoadException exception) {
....
}
}
}
モジュール定義:
public class MyExtraModule : IMyModuleRegistration
{
public void RegisterComponents(IKernel kernel)
{
kernel.Bind<IService>()
.To<ExtraService>()
.When(x => x.ParentContext
.Kernel.Get<IAuthorizationService>()
.IsVIPUser());
}
}
ExtraService
MyExtraModule
のdllがロードされている場合にのみ使用されます。
編集2
そのdllはどこかからダウンロードできます。ロードしてから、登録インターフェイスが実装されているかどうかをテストします。次に、その登録を呼び出して、完了です。私が見る唯一の問題は、参照をどこに保存するかですIKernel
-おそらくいくつかの静的プロパティでHttpApplication
十分でしょう。また、すでにロードされているdllを追跡する必要があります。
または、それ以降のバージョンでは、を拡張して、メソッドを使用してカーネルにロードするNinject
ことを提案できます。このモジュールとカーネルを見てください-特に部分的に動的モジュールの読み込み-多分それはあなたが探しているものです。NinjectModule
kernel.Load(..)