0

Consider a situation where you have some controller that uses some service which is injected by some IOC container like autofac or ninject. Service is initialized each time a request hits that controller, even if it just wants to trigger simple action that only calls a view. The question here is how to defer initialization for a service for when it's really needed so I can save some resources. Should I use here Lazy? Or perhaps should I inject this services into method instead of controller?

Example:

public class SomeController : Controller
{
    private readonly ISomeService _service;

    public SomeController(ISomeService service)
    {
        this._service = service;
    }

    // action that completely doesn't need to initialize service
    public ActionResult Index()
    {
        return View();
    }
    // this action needs to initialize 
    public ActionResult Save()
    {
        this._service.DoSomething();
        return View();
    }
}
Piotr Ptak
  • 461
  • 6
  • 15
  • You could implement property injection, so it will be injected when the getter (to the service) is called the first time. – EluciusFTW Mar 06 '17 at 11:13
  • 1
    Did you run a performance test to see what the difference is and whether this actually matters for your application? – Steven Mar 06 '17 at 11:59
  • Why would the a reference to `Lazy` be quicker store than a reference to `T` ? – Maarten Mar 06 '17 at 12:10

2 Answers2

3

Just a few thoughts!. The constructor of your class (controller in this case) should not do anything except store the dependencies, for which it has to resolve the dependencies when the controller is resolved.

When you use any DI framework the container need to upfront know the dependency hierarchy and their lifetime management scopes so that when requested by any component, the container can provide the resolved instance. You could use faster DI container if you are worried about the performance aspect of it.

If the creation of your injected object is expensive (I tend to keep it simple, by not having to much logic in the initialization) then one thing to consider might be to have a Singleton or Per Request lifetime scope for the object (if its possible)

Steven
  • 166,672
  • 24
  • 332
  • 435
Jinish
  • 1,983
  • 1
  • 17
  • 22
  • I have done some further research and I think instance per request configuration with seldom use of Lazy is fine. I accepted your answer, thank you – Piotr Ptak Mar 06 '17 at 13:13
1

Yes, most decent IoC containers allow you to inject Lazy<T> and defer initialization until the lazy object is used. Usually this just works automatically if you change the type of the constructor parameter from T to Lazy<T>

Specifically, I believe this is built into autofac, and can be added to ninject using the module Ninject.Extensions.Factory

Jonas Høgh
  • 10,358
  • 1
  • 26
  • 46