0

I am new to autofac. I am using it on my new web api 2 project. The following is my autofac config code called by the Global.asax's Application_Start() method. I am not sure whether my usage of InstancePerRequest() is correct or not. More importantly, is it even need to be used at all? Or, instead I should use other options such as InstancePerLifeTimeScopre() or InstancePerDependency()? Whether I use any of these lifetime scope options or not, during debug, they produce same results.

public class IocConfig
{
    //Autofac configuration
    public static void Configure()
    {
        ContainerBuilder builder = new ContainerBuilder();
        builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
        builder.RegisterType<DeliveryCode>().As<IDeliveryCode>() 
         .InstancePerRequest();
        builder.RegisterType<DeliveryContext>().As<IDeliveryContext>()
         .InstancePerRequest();
        builder.RegisterType<DeliveryStrategy>().As<IDeliveryStrategy>() 
         .InstancePerRequest();
        IContainer container = builder.Build();
        AutofacWebApiDependencyResolver resolver = new 
            AutofacWebApiDependencyResolver(container);
        GlobalConfiguration.Configuration.DependencyResolver = resolver;
    }
}
Massey
  • 1,099
  • 3
  • 24
  • 50
  • 1
    Let's say your controller has two dependencies - `IBob` and `ICathy`. `Bob` has a dependency on `ICathy` as well. If `ICathy` is registered as `InstancePerDependency` then two instances of `Cathy` will be created. If `InstancePerLifeTimeScope`, only one will be created. Which is correct? Well, it depends on whether you want 1 or 2. – mjwills Jan 21 '19 at 22:41

2 Answers2

1

InstancePerDependency - you get a new object for each dependency. Objects are never shared among clients. I'd say use this only if needed, as it is slower and uses more memory than others. But it is very safe, because each dependency is a private object.

InstancePerRequest - you get a new object for one web api call. This is useful when you want to create a new object for each api call, but then to share it among all other objects during this particular api call.

InstancePerLifeTimeScope - this one is similar to previous, but more generic. You normally don't need this, just ignore. :-)

SingleInstance - this creates just a single instance globally, shared among different web api calls and everything. Useful for global data providers, stateless classes offering a "service" to others etc.

Note that the "per dependency" and "single instance" are the opposite of each other. And "per request" is something in between, tailored for web api. :-)

Also note that if you tried them and they seem to behave identically, it can be because your test is wrong. But also it can be truth - stateless services can be registered as any type and will work correctly. It is just less efficient if you use per-dependency in cases where other registration types are suitable. Similarly it is less efficient to use per-request in case where singleton is suitable. But this is all just optimization. On the other hand, if your class is stateful and you mistakenly register it as singleton when you actually need separate instances, your program will behave wrongly and that's bigger problem than insufficient optimization.

Al Kepp
  • 5,831
  • 2
  • 28
  • 48
  • `You normally don't need this, just ignore. :-)` No, don't. Use it rather than `InstancePerRequest` **because** it is more generic. https://stackoverflow.com/questions/12127000/autofac-instanceperhttprequest-vs-instanceperlifetimescope https://autofaccn.readthedocs.io/en/latest/lifetime/instance-scope.html#instance-per-request `What this means is that if you try to resolve components that are registered as instance-per-request but there’s no current request… you’re going to get an exception.` – mjwills Jan 21 '19 at 23:47
  • @mjwills technically, you are correct. But do you really think that a beginner will need it? I don't think so. People who are just starting with web api can ignore it. But thanks for clarification, anybody can now click the link and read more info. :-) – Al Kepp Jan 22 '19 at 00:09
  • 1
    I think it is a good habit to always use `InstancePerLifeTimeScope`. Thus it will work in MVC, WebAPI, and .NET Core. If there is one way that will _always_ work (like `InstancePerLifeTimeScope`) then I'd encourage it - especially for beginners. – mjwills Jan 22 '19 at 00:32
  • According to this excellent article, http://decompile.it/blog/2014/03/13/webapi-autofac-lifetime-scopes/ InstancePerDependency() seems to be the default. Al Kepp explained above that it's the safest although slower. So, I have removed InstancePerRequest() from my code, which will then default to InstancePerDependency(). Thanks, everyone for your inputs! – Massey Jan 22 '19 at 18:32
0

Determining the lifetime of your dependencies really depends on the needs of your application. For example, if you have a dependency that is used to retrieve constant values, it may be best suited as a singleton so that those values are only retrieved once throughout the lifetime of your application.

If you haven't already, I'd recommend checking out the Autofac documentation on "Controlling Scope and Lifetime". It provides a good overview of the differences between the types of instance scopes (i.e. InstancePerLifeTimeScope() or InstancePerDependency()) and how they behave.

devNull
  • 3,849
  • 1
  • 16
  • 16