Нет, вы не можете связать «после» - во-первых, веб-приложения не имеют состояния и не контролируют порядок событий, но, что более важно, модули Ninject определяют ваш контейнер IoC, и эта конфигурация происходит почти до что-нибудь еще в жизненном цикле приложения или запроса.
Если вы говорите, что пользователь выберет это из раскрывающегося списка, то выбор хранилища является частью вашей логики приложения , а не частью вашей конфигурации IoC. Способ справиться с этим - создать фабричный интерфейс. Реализация может быть тонкой оболочкой вокруг самого ядра Ninject.
public interface IRisksRepositoryFactory()
{
IRisksRepository GetRepository(string name);
// Optional: add a GetRepositoryNames() method for populating dropdowns, etc.
}
public class NinjectRisksRepositoryFactory
{
private readonly IKernel kernel;
public NinjectRisksRepositoryFactory(IKernel kernel)
{
if (kernel == null)
throw new ArgumentNullException("kernel");
this.kernel = kernel;
}
public IRisksRepository GetRepository(string name)
{
return kernel.Get<IRisksRepository>(name);
}
}
Для этой конкретной реализации вам нужно убедиться, что вы используете именованные привязки (хотя, вообще говоря, вы также можете использовать систему метаданных), и делать каждую привязку явно:
Bind<IRisksRepository>()
.To<MySqlRisksRepository>()
.InRequestScope()
.Named("mysql")
.WithConstructorArgument("connectionString", GetConnectionString("mydb1"));
Bind<IRisksRepository>()
.To<OracleRisksRepository>()
.InRequestScope()
.Named("oracle")
.WithConstructorArgument("connectionString", GetConnectionString("ordb1"));
Bind<IRisksRepositoryFactory>()
.To<NinjectRisksRepositoryFactory>();
Также возможно сделать это без явного создания каждой привязки, особенно если все цели имеют одинаковый тип (т. Е. У вас есть только MySqlRisksRepository
), передав строку подключения или связанный символ в качестве параметра Get
вызов и привязка к контекстному методу, а не к типу - но я бы рекомендовал против этого, так как он действительно плавает против течения, насколько вообще DI идет.
Еще одна вещь: не беспокойтесь, что это напоминает антишаблон "локатор служб", потому что это все, что есть - поверхностное сходство. Когда объекты должны иметь возможность создавать зависимости на лету, рекомендуется создавать фабрики специального назначения вокруг контейнера IoC, поскольку это сводит к минимуму воздействие ядра на один класс, который можно легко заменить, если вы переключитесь на другую среду.