Search code examples
c#dependency-injectionautofac

inconsistency of RegisterInstance method and InstancePerDependency lifetime scope


I'm new to Autofac, one API of Autofac lets you provide an instance (without using Reflection) you create as:

var builder = new ContainerBuilder();

MyClass myClass = new MyClass();
builder.RegisterInstance<MyClass>(myClass);

But the API also allows you to further control the lifetime as transient:

builder.RegisterInstance<MyClass>(myClass).InstancePerDependency();

so if you resolve it in child lifetime scopes as:

IContainer container = builder.Build();

using (var childScope1 = container.BeginLifetimeScope()) {
   MyClass myClass1 = childScope1.Resolve<MyClass>();
   ...
}

using (var childScope2 = container.BeginLifetimeScope()) {
   MyClass myClass2 = childScope2.Resolve<MyClass>();
   ...
}
...

You will get the same instance you created when you new up the instance, so you won't have a different MyClass instance every time you request, which is the purpose of Transient lifetime. So it doesn't really make sense to use InstancePerDependency or InstancePerLifetimeScope method with RegisterInstance method, that's what I thought. But since the API allows you to do that, so what does it really mean?


Solution

  • This is the second question you've asked where you're providing a repro and you haven't actually run the code.

    If you run code where you register and instance and then later try to change its lifetime scope, you get an exception.

    System.InvalidOperationException : The instance registration 'MyClass' can support SingleInstance() sharing only.

    Put another way, you can't change it from an instance to instance-per-dependency or anything else. The example won't work.

    I recognize there are some hypothetical situations that it appears will work because it compiles, but since dependency injection is largely based on wiring things up at runtime there are many errors that won't be caught until the container is built and things are all hooked together.

    I would recommend slowing down to speed up: Instead of writing up code that's hypothetical and wondering what happens, you can answer a lot of your own questions by setting up a little scratch project that just has Autofac and Xunit in it. Write a tiny set of unit tests to validate theories or check things out. It can save you a lot of time in trying to write up questions, it'll save us out here time trying to answer questions, and it'll give you a far deeper understanding of how things are working by getting some hands-on experience.