Reputation: 1944
I have some code that I'm looking to refactor that looks something like this:
public static class RepositoryFactory
{
public static IRepository Create(RepositoryType repositoryType)
{
switch(repositoryType)
{
case RepositoryType.MsSql:
return new MsSqlRepository();
break;
case RepositoryType.Postgres:
return new PostgresRepository();
break;
//a lot more possible types
}
}
}
Which is being called based on parameters from an HTTP request:
public ActionResult MyAction()
{
var repoType = RepositoryType.MsSql; //Actually determined from HTTP request, could be any type.
var repository = RepositoryFactory.Create(repoType);
}
So what I'd really like to do is refactor so that my controller looks like this:
[Inject]
public ActionResult MyAction(IRepository repository)
But since RepositoryType
could change on each request, I can't figure out how to leverage ninject's conditional binding to make that happen. I know how to use conditional binding in general, such as Bind<IRepository>().ToMethod()
and Bind<IRepository>().To<MsSqlRepository>().WhenInjectInto()
etc, but I can't figure out what to do when the binding condition is coming from an outside source.
Upvotes: 1
Views: 129
Reputation: 13243
This should actually be fairly easy:
kernel.Bind<IRepository>().To<MsSqlRepository>()
.When(ctx => System.Web.HttpContext.Current.... (condition here) );
kernel.Bind<IRepository>().To<PostgresRepository>()
.When(ctx => System.Web.HttpContext.Current.... (condition here) );
You can also define one as a "default" and the other as a conditional one:
// this will be used when there's not another binding
// for IRepository with a matching When condition
kernel.Bind<IRepository>().To<MsSqlRepository>();
// this will be used when the When condition matches
kernel.Bind<IRepository>().To<PostgresRepository>()
.When(ctx => System.Web.HttpContext.Current.... (condition here) );
Upvotes: 1