Search code examples
asp.net-mvcinterfaceinversion-of-controllinfu

Is there a better way to do IOC in asp.net-mvc?


I have an asp.net-mvc site and I am using LinFu to do IOC. I ran into an issue where a number of actions have a dependency that I want to inject into the controller but i only want to initialize the dependency if i call the action that depends on it.

so in my controller I have this code in my controller:

   public PersonController
   {

    private IPeopleImporter _peopleImporter;

    public override void Initialize(LinFu.IoC.Interfaces.IServiceContainer source)
    {
        _peopleImporter= source.GetService<IPeopleImporter>();
        base.Initialize(source);
    }

    public JsonResult GetDetails(int id)
    {
        var p = _peopleImporter.Get(id);
        var personDetails = new {p.Id, p.FirstName, p.LastName, StandardId = p.StandardIdLogin, p.PersonNumber};
        return Json(personDetails);
    }
   }

to initiatize PeopleImporter is pretty expensive so my issue is that I want to solve two things:

  1. I want to make the implementatioo of IPeopleImporter "pluggable" so I can IOC in the interface into the controller

  2. I have a lot of actions so I don't want the cost of initiatizing the IPeopleImporter if the user never calls the specific action that needs it. It seems like in the code above I do that initiatization on every call of PersonController

My initiatization code is like this:

this.AddService(typeof(IPeopleImporter), typeof(DatabaseImporter), LifecycleType.Singleton);

This seems like common pattern / issue. Is there a recommended solution. in the meantime, the alternative (to avoid the performance hit is to simple "new" up the concete implmentation inside the controller (and avoid IOC) ?


Solution

  • You can use next trick for your task. You can inject not instance of IPeopleImporter but factory of this type:

    private readonly Func<IPeopleImporter> _peopleImporterFactory;
    

    and use this factory in your action where you need it:

    var peopleImporter = __peopleImporterFactory();
    

    example:

     public PersonController
    

    {

    private readonly Func<IPeopleImporter> _peopleImporterFactory;
    
    public PersonController(Func<IPeopleImporter> peopleImporterFactory)
    {
        _peopleImporterFactory = peopleImporterFactory;
    }
    
    public JsonResult GetDetails(int id)
    {
        var peopleImporter = _peopleImporterFactory();
        var p = peopleImporter.Get(id);
        var personDetails = new {p.Id, p.FirstName, p.LastName, StandardId = p.StandardIdLogin, p.PersonNumber};
        return Json(personDetails);
    }
    

    }