使用Ninject的参数化工厂

use*_*159 1 c# ninject factory-pattern ninject.web.mvc

如何使Ninject在运行时基于变量实例化对象?

我试图在控制器动作中注入正确的存储库 - MVC 3 - 基于来自用户输入的参数.如果用户输入"宝马",将绑定ICarRepositoryBMWRepository,如果他输入"KIA" KiaRepository将被注入.

[HttpPost]
public ActionResult SearchResult(FormCollection values)
{
    string carModel  = values["model"];

    ICarRepository myRepository = RepositoryFactory.getRepository(carModel);

    .....
}
Run Code Online (Sandbox Code Playgroud)

这是通过开关/案例noob实例化或参数化工厂知道的,我知道如何在没有Ninject的情况下手动完成,请查看此处介绍的4种方法探索工厂模式

我的问题是如何用Ninject做到这一点?

Rub*_*ink 5

你可以注入一个抽象工厂(可能只是一个Func<string,ICarRepository>)然后通过添加以下内容来实现它RegisterServices:

Bind<ICarRepository>().To<KiaRepository>().Named("KIA")
Bind<ICarRepository>().To<BmwRepository>().Named("BMW")
Bind<Func<string,ICarRepository>>()
    .ToMethod( ctx=> name => ctx.Get<ICarRepository>( name));
Run Code Online (Sandbox Code Playgroud)

在你的ctor:

class MyController
{
    readonly Func<string,ICarRepository> _createRepository;

    public MyController(Func<string,ICarRepository> createRepository)
    {
        _createRepository = createRepository;
    }
Run Code Online (Sandbox Code Playgroud)

然后,在你的行动中:

[HttpPost]
public ActionResult SearchResult(FormCollection values)
{
    string carModel  = values["model"];

     using( ICarRepository myRepository = _createRepository( carModel)) 
     {
            ... 
     } 
}
Run Code Online (Sandbox Code Playgroud)