Is there a way to make Autofac to always resolve types in a new lifetimescope?
ie.
Container.Resolve<MyHandler>().Whatever();
Now i have to do like this:
Container.BeginLifetimeScope().Resolve<MyHandler>().Whatever();
It would be nice to be able to inject MyHandler into a class and know that MyHandler is it own scope.
Autofac does not provide a way to automatically start a new lifetime scope per component resolution.
Creating a lifetime scope is actually a process you need to control very tightly. Lifetime scopes not only help the scoping of component resolution, but also manage the deterministic disposal of components you resolve. From a memory management perspective, you shouldn't just fire up lifetime scopes without also disposing of them when you're done. Failing to dispose your created scopes can very easily cause a memory leak.
This is why you always see BeginLifetimeScope in a using statement or in a very tightly integrated scenario like ASP.NET request lifetime - so you can start a scope at a known spot and be sure to end/dispose of it. Child lifetime scopes are not automatically disposed for you once they're created - it's up to you to do that cleanup.
The Autofac wiki has some good information on lifetime scopes here.
Related
I have an autofac module which implements IDisposable. The module is registerd with the containerBuilder.RegisterModule<> method and it gets resolved during container.Build. But: Dispose is not called on the module when container gets disposed.
Is this a bug, or do i miss something?
I have reproduced this with Autofac 4.6.2 and 4.8.1, didn't test other versions between.
Modules are not meant to be disposed. The link between Autofac and disposable components is fulfilled by the ILifetimeScope implementations.
A module is basically a box with a Load method, that gets executed once.
When the Load method completes, you must be done with the module.
So, if you have any resource to be kept alive and disposed afterwards, it should be kept alive (and disposed) in one of the lifetime management options.
So, you could say it's a bug, but I personally think it's just a case of a feature that is not needed for the intended use of the modules (this last phrase is just my personal opinion).
If you care to describe (maybe in another question?) what is the actual problem you're trying to solve with a disposable module, we can discuss that.
In Startup.cs it's possible to control dependency injection lifecycle using transients and singletons. However it's unclear how the lifecycle works when using .AddDBContext like so services.AddDbContext<DatabaseContext>(...);
Each controller uses this dependency by initialising it only once in the constructor and is reused throughout by the controller functions.
Is the context initialised for each request or is there a possibility this context being shared between user sessions resulting in bad state?
Note: duplicate question does not address if context is being shared between user sessions.
services.AddDbContext<>(...); registers your DbContext with Scoped lifetime. That means a new instance is created for every single request. No need to worry it would be shared with other connections.
I'm using an Autofac container for the entire lifetime of my application, but I want to dispose the components myself.
I.E if I have builder.RegisterType<SomeType>(), I don't want the container to keep references of SomeType which will keep those alive even if not referenced anywhere else (if RegisterInstance is used OTOH, then of course the container must keep a reference to the singleton).
I can see that I can do builder.RegisterType<SomeType>().ExternallyOwned() which solves my problem for one type, but I don't want to write it for every type, and more importantly I also use builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource()); which doesn't give me the option of using ExternallyOwned.
Is there a way to specify "ExternallyOwned" for the entire container? Or, to put it another way, tell the container to disable the entire dispose feature and not keep references for objects it doesn't need?
There is not a way to disable container disposal services. You might try to hook in with something like the logging module but I could see that not working 100% and missing edge cases of you're not careful.
Automatic tracking and disposal is a pretty common container feature. I'd recommend instead of fighting it you refactor your code to embrace it. It'll make life a lot easier.
I am very new to Autofac dependency injection and I got these questions related to my project. I have gone through many articles but I am not getting a clear picture on some of the questions I have. Mine is a service application on .Net REST API. I am doing instance registration in App_Start module as shown below.
private static IContainer RegisterServices(ContainerBuilder builder)
{
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
builder.RegisterType<DCLMessengerContext>()
.As<DbContext>()
.ExternallyOwned()
.InstancePerLifetimeScope();
builder.RegisterType<DbFactory>()
.As<IDbFactory>()
.ExternallyOwned()
.InstancePerLifetimeScope();
builder.RegisterType<UnitOfWork>()
.As<IUnitOfWork>()
.InstancePerLifetimeScope();
builder.RegisterGeneric(typeof(EntityBaseRepository<>))
.As(typeof(IEntityBaseRepository<>))
.InstancePerLifetimeScope();
builder.RegisterType<PersonServiceClient>()
.As<IPerfService>()
.InstancePerLifetimeScope();
builder.RegisterType<PagingServiceContractClient>()
.As<PagingServiceContract>()
.InstancePerLifetimeScope();
builder.RegisterType<MessageService>()
.As<IMessageService>()
.InstancePerLifetimeScope();
Container = builder.Build();
return Container;
}
My service layer is "MessageService" and there I am performing all the DB and other integration operations and getting the instances through constructor injection. These are the questions I have around this implementation.
I am using InstancePerLifeTimeScope for all my registrations. Is this is the right approach? After the life cycle of each controller request (http request), will these instances will be automatically disposed?
Do we need to manually implement any Dispose operation on any of these instances? ( I don’t have any unmanaged objects in my code)
From the service method, I need to create a fire&forget thread as well using Task.Run(). What is the best approach to supply instances to this fire&forget thread? If I use InstancePerLifeTimeScope, I can see that new thread also getting the same instances that available through the service class so I am just confused when these instances will be disposed?
When you resolve the instance per lifetime scope component, you get a
single instance per nested scope
So if you are using them in controllers. You will have one object for per request and they will be disposed. But if you resolve them in a singleton object they wil live with this object.
Is this is the right approach?
It depends what you need. If you need singleton object, it's not. If you just want to use this service in request scope use instanceperrequest it's better.
Autofac automatically calls dispose for IDisposable objects. If you
need dispose method, implement it. It's not related with autofac.
If you use another thread resolve objects in this thread. Otherwise when request disposed your objects will be disposed and your thread will be fail. Check this.
I'm building a plugin for a 3rd party application and my plugin uses Autofac to wire up various components. The container is built at application startup, but the host application invokes my commands at a later time.
When a command is invoked, the host application provides a few instances of types that it defines and that my components will need to use. I'd like to register these instances in the container so that it can take care of wiring up the components that depend on these instances.
I'm aware that I can use a ContainerBuilder to update an existing container, but I'd like to remove these registrations when the command has completed as these instances will no longer be valid. Is this possible?
Maybe a better approach is to use 2 containers... The command could create a new container to register these instances and other components could be resolved from the application scoped container.
How could I hook up the 2 containers so that resolve calls bubble up to the application scoped container?
Are there any gotchas to be aware of with this approach? I imagine there may be component lifetime issues...
Edit: Now I've done a bit more research and testing and and it turns out I can just use the BeginLifetimeScope(Action<ContainerBuilder>) overload to register the host application provided instances for the nested lifetime only. For some reason I thought that adding registrations to the nested lifetime would result in them being added to the root container but that doesn't seem to be the case.
As noted in my edit above, it turns out that BeginLifetimeScope(Action<ContainerBuilder>) is exactly what I need. For some reason I thought that adding registrations to the nested lifetime would result in them being added to the root container and therefore being resolvable after the nested lifetime scope ends, but that doesn't seem to be the case.