Search code examples
c#ninjectfactory-patternninject.web.mvc

Parameterized Factories Using Ninject


How to make Ninject to instantiate object based on variable on run time?.

I am trying to inject the correct Repository in The Controller action - MVC 3 - based on parameter come from user input. If user input "BMW" it would bind ICarRepository to BMWRepository , and if he input "KIA" KiaRepository will be injected.

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

    ICarRepository myRepository = RepositoryFactory.getRepository(carModel);

    .....
}

This is known by switch/case noob instantiation or Parameterized Factories, and i know how to do it manually without Ninject , Check the 4 approaches explained here Exploring Factory Pattern

My question is how to do it with Ninject?


Solution

  • You could inject an Abstract Factory (probably just a Func<string,ICarRepository>) and then have it all implemented via adding the following to your RegisterServices:

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

    In your ctor:

    class MyController
    {
        readonly Func<string,ICarRepository> _createRepository;
    
        public MyController(Func<string,ICarRepository> createRepository)
        {
            _createRepository = createRepository;
        }
    

    Then, in your action:

    [HttpPost]
    public ActionResult SearchResult(FormCollection values)
    {
        string carModel  = values["model"];
    
         using( ICarRepository myRepository = _createRepository( carModel)) 
         {
                ... 
         } 
    }