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. |
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: