如何使用 ninject 替换存储库工厂
How to use ninject to replace a repository factory
我有一些代码需要重构,看起来像这样:
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
}
}
}
根据 HTTP 请求的参数调用:
public ActionResult MyAction()
{
var repoType = RepositoryType.MsSql; //Actually determined from HTTP request, could be any type.
var repository = RepositoryFactory.Create(repoType);
}
所以我真正想做的是重构,使我的控制器看起来像这样:
[Inject]
public ActionResult MyAction(IRepository repository)
但是由于 RepositoryType
可能会根据每个请求发生变化,我不知道如何利用 ninject 的条件绑定来实现这一点。我知道如何使用一般的条件绑定,例如 Bind<IRepository>().ToMethod()
和 Bind<IRepository>().To<MsSqlRepository>().WhenInjectInto()
等,但是当绑定条件来自外部来源时,我无法弄清楚该怎么做。
这实际上应该相当简单:
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) );
您也可以将一个定义为 "default",将另一个定义为有条件的:
// 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) );
我有一些代码需要重构,看起来像这样:
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
}
}
}
根据 HTTP 请求的参数调用:
public ActionResult MyAction()
{
var repoType = RepositoryType.MsSql; //Actually determined from HTTP request, could be any type.
var repository = RepositoryFactory.Create(repoType);
}
所以我真正想做的是重构,使我的控制器看起来像这样:
[Inject]
public ActionResult MyAction(IRepository repository)
但是由于 RepositoryType
可能会根据每个请求发生变化,我不知道如何利用 ninject 的条件绑定来实现这一点。我知道如何使用一般的条件绑定,例如 Bind<IRepository>().ToMethod()
和 Bind<IRepository>().To<MsSqlRepository>().WhenInjectInto()
等,但是当绑定条件来自外部来源时,我无法弄清楚该怎么做。
这实际上应该相当简单:
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) );
您也可以将一个定义为 "default",将另一个定义为有条件的:
// 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) );