Reputation: 5302
I was wondering how Autofac handles IAsyncDisposable with the regular lifetimes.
Let's say we have a component registered via
builder.RegisterType<DnsResolutionService>()
.As<IDnsResolutionService>()
.SingleInstance();
While reading the docs I found the following:
While you do not have to implement IDisposable if you implement IAsyncDisposable, we strongly recommend you do so. If your component only implements IAsyncDisposable, but someone disposes of the scope synchronously, then Autofac will throw an exception, because it does not know how to dispose of your component.
I'm a bit confused now, and essentially I have two questions in my head:
Do the regular lifetime scopes added to a registration fully support async disposing? Or does a synchronous disposal only happen if I explicitly use something like using(var scope = container.BeginLifetimeScope())
- Which I actually basically never use due to only using constructor injection.
In case something would actually try to dispose my component, which would implement both IDisposable
and IAsyncDisposable
, as the docs suggest, in a synchronous way, then it will probably only call IDisposable. In this case, do I have to dispose all my IAsyncDisposables in the synchronous dispose block as well? Does Autofac provide any kind of order, e.g. IAsyncDisposable is called first, so I can maybe keep track of what's already disposed and what isn't? Or do I have to manage this myself?
Upvotes: 0
Views: 1090
Reputation: 36483
I'll try to answer your questions, but there's a 'depends' in there, just to warn you.
All the lifetime scopes fully support asynchronous disposal. If you are using the ASP.NET Core integration, then lifetime per-request scopes will always be automatically disposed of using the DisposeAsync
method. However if you create a lifetime scope some other way, you will need to use await using
yourself to make it dispose asynchronously.
This one depends on how you are consuming those resources you need to clean up.
If your component takes dependencies on services injected by Autofac, and those services are not ExternallyOwned, then don't dispose of them yourself, let Autofac take care of that for you. Autofac knows to invoke the synchronous Dispose
on a component if the scope is being disposed asynchronously, but the component doesn't implement IAsyncDisposable
.
If you are injecting ExternallyOwned
components, or allocating resources inside your component that Autofac doesn't know about, you will need to dispose of those yourself, either using Dispose
or DisposeAsync
as required, in the normal way.
Upvotes: 2