-
Notifications
You must be signed in to change notification settings - Fork 48
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
Issue with disposable singletons #15
Comments
Duplicate of autofac/Autofac#780 |
@tillig I don't think this is a duplicate of autofac/Autofac#780 Autofac.Extensions.DependencyInjection is an adapter for Autofac in order to act as a substitute for Microsoft ASP.NET DependencyInjection when using the conforming container pattern. The problem here is: when you are using the original DI container from Microsoft the behavior is different compared to the implementation of the adapter. I think the issue can simply be resolved by checking if the descriptor of the singleton service contains a |
It's a duplicate because when you're using the Autofac adapter the thing fulfilling requests is not the Autofac adapter it's the Autofac container. The shell implementations of To be clear, there will definitely be behavior differences between the Autofac DI container and the Microsoft DI container. We're not trying to behave identically - if you choose to use Autofac as your backing container, you're also choosing the Autofac behaviors. The difference in behavior you found is one of probably many; it just happens that we've been having a discussion about how Autofac should handle it (and, by virtue of that, how the Autofac.Extensions.DependencyInjection adapter will behave). What you've stumbled into inadvertently is a fairly huge discussion where Microsoft has created a container (rather than just abstractions/interfaces) and developers somewhat assume if they switch backing containers that behavior will be identical - that there's a conforming container here. You can see it in issues and blog entries like this where many different container owners are concerned about that: |
Interesting - the behaviour described here is really quirky (the difference between registration at container level as opposed to registration at scope level with a different behavior on disposal). So I understand your point. But do you have an idea how to keep the externally owned instance (see my initial example) from getting disposed when the container is disposed? In Autofac I could use |
The workaround now is to register directly with Autofac instead of the adapter. For the adapter, we need to solve the behavior in the core container. We are using RegisterInstance in the adapter (which is correct) but it's not behaving consistently. Once figure out what core Autofac should do, that's what the adapter will also do. The adapter will behave like Autofac. If you want to follow autofac/Autofac#780, that's where this is being discussed. |
From my perspective the issue comes from a gap in the overall design of dependency injection containers. That is not only an autofac issue. Often dependency containers work as a service registries and service factories at once. From the client side it is not possible to decide who is responsible for disposing an object. This detail is provided by the registration but not forwarded appropriately to the client. Or did I oversee something? |
Disposable services are typically registered as scoped services, so the container is responsible for disposing them. Therefore I think an injected service should never be disposed by the instance that get the service injected. Only services that are created by an (injected) service factory should be disposed by the code that uses the factory. |
This looks like a terrible workaround. Why can't Autofac's implementation just check for the The
The latter is clearly externally owned. |
We've had some discussion today over the contract of the None of those conforming container tests currently specify/enforce that singleton instances registered by This behaviour of not disposing instances is therefore implicit (albeit documented) behaviour of MSDI. Note that this is the opposite of the Autofac defaults. There are other implicit behaviours as well that aren't in the conforming container tests. All that being said, the contract of the The user expectation here is that calling So, we now plan to make a change in this Autofac integration to map in that manner and make singleton provided instances ExternallyOwned. Here's what we're going to do:
|
That's a really nice plan Alistair, agreed on all fronts. In particular, I'm surprised this behavior wasn't part of that set of tests on MS' side: it should definitely be there and I'm glad you are making a proposal to include it. On a side note, you might want to remove the |
Let's assume we have the following types:
When using Microsoft ASP.NET DependencyInjection the following code works correctly:
The externally owned singleton is not disposed - that's correct.
The following code works correctly, too:
Here the singleton
myObj
is disposed, because it is created inside of a lamdba factory function -correct so far.
Now let's see what Autofac using the Microsoft ASP.NET DependencyInjection adapter is doing:
The externally owned singleton is disposed on container disposal - this is not correct.
When using a lambda factory function, Autofac is working correctly:
The singleton is disposed as expected.
Used versions:
The text was updated successfully, but these errors were encountered: