-
-
Notifications
You must be signed in to change notification settings - Fork 837
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding IAsyncDisposable Support to Autofac #1037
Conversation
…ests to verify that the async dispose follows down onto the individual services.
Would it make sense to add the support for The default Microsoft-Service-Provider also provides this functionality as can be seen here and is actually implemented somewhere deep down in ServiceProviderEngineScope. We have two different implementations of If so, it would probably be needed in the MultitenantContainer as well. |
Yes, it absolutely should, the support for this in ASP.NET Core was actually my main reason for introducing these changes. :) I've already done the I haven't raised a PR for that yet because it'll wait until there's a pre-release package with the changes from this PR. I believe that simply deriving from the It is worth noting (as I discovered) that it is the Changes will be needed in the Autofac.MultiTenant integration, to enable async dispose on the |
Okay cool :) I will take on the changes required for the |
…dded conditional package reference for netstandard2.0.
@alsami, yes, perfectly happy for you to take on the multitenant changes! I've changed Autofac to target netstandard2.1 instead of netcoreapp3.0, and added the Microsoft.Bcl.AsyncInterfaces @davidfowl mentioned for netstandard2.0 only. Also changed all the |
Since this would be part of the 5.0 release, wouldn't it make sense to drop support for |
@alsami, I understand the desire to drop support for net45 and that would be nice... However, there will be people out there (including myself sadly) who work with a couple of projects that can't move from 4.5.2 for various reasons, and it seems harsh to deprive those projects of future upgrades of Autofac just for the sake of a few compiler directives. Happy to go with the owner ruling on this though whichever way it goes. |
If that is the case I totally agree with you. To be honest I never came across a project that couldn't be updated from 4.x to 4.6.1. I always dream about not having to boot into my windows virtual machine to edit some .NET-project 🤣 |
I think we should drop |
…if blocks for async dispose support.
…etadata> reference problems and update/remove other incompatible #if statements after the targeting changes.
@alexmg, I've updated the changes so Autofac now targets Initially I only had |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking good. Removing net45
definitely reduced the noise. Please use await
in the DisposerTests
and this is good to go.
Nice contribution @alistairjevans! 👏 This is now available in the |
I've made what I believe are the necessary changes to make asynchronous disposal of lifetime scopes work. See https://docs.microsoft.com/en-us/dotnet/api/system.iasyncdisposable?view=dotnet-plat-ext-3.0 for some background.
This now works:
I've added framework targeting for netcoreapp3.0, and made all the
IAsyncDisposable
support conditional on that target.The main changes for this are in the
Disposer
, which has to now handle async dispose of all registered objects. The locking mechanism to sync access to the set of tracked objects has changed from a lock statement to aSemaphoreSlim
, because theMonitor
does not work in an async context. BothIDisposable
items andIAsyncDisposable
items can be added to the same Disposer, and they will be disposed in the same order as they would have been with normalDispose
. Objects that only have anIAsyncDisposable
implementation will cause an exception to be thrown if aLifetimeScope
is then disposed of synchronously. This matches the behaviour of the main .NET DI system.The
Disposable
base class has been updated to implementIAsyncDisposable
, and provide default functionality of calling synchronousDispose
if an implementing class does not need to supportDisposeAsync
. Container and LifetimeScope do implementDisposeAsync
, so they can Dispose of the root lifetime scope and the scope'sDisposer
respectively.There's an associated set of changes needed in the DependencyInjection integration, which I have locally, to allow the Autofac lifetime scope to get cleaned up async on scope end, by implementing IAsyncDisposable on the relevant framework types.
I've added a selection of tests to check that async behaviour works as expected, and plays nicely with normally-disposed and async-disposed objects.