Reputation: 3590
I'm using Microsoft.Extensions.DependencyInjection
(default implementation). I noticed that when I'm adding my object as singleton then ServiceProvider
ignores IDisposable
on my object.
var instance = new MyDisposableObj();
ServiceLocator.Instance = instance;
var services = new ServiceCollection();
services.AddSingleton( instance );
var container = services.BuildServiceProvider();
container.Dispose();
Looks like microsoft think that I have to manually dispose objects which are created manually.
But in the case when I do the extension for ServiceCollection I want to encapsulate disposing of my object. I shouldn't force the users of my extension to dispose my object manually!
So, is it possible to change this behavior?
Upvotes: 2
Views: 5870
Reputation: 2125
There is another option, I think - more proper. Look at ServiceProvider. It implements IDisposable. It means that you should create ServiceProvider by using statement:
using(var provider = collection.BuildServiceProvider()) { var service1 = provider.GetRequiredService(); }
And that's all.
Upvotes: 1
Reputation: 61
I know this is old but maybe it will help to clarify a bit.
You can create object yourself and register using implementation factory. DI will take care of disposing object, as it is taking ownership of it by calling factory method.
It is described in msdn.
var instance = new MyDisposableObj();
var services = new ServiceCollection();
services.AddSingleton(x => instance);
var container = services.BuildServiceProvider();
container.Dispose();
You can verify this with simple unit test
[Fact]
public void ServiceProvider_SingletonObjectAddedAsFactory_IsDisposedWithContainer()
{
// Arrange
var sc = new ServiceCollection();
var fake = A.Fake<IDisposable>();
sc.AddSingleton(x => fake);
// Act
var sp = sc.BuildServiceProvider();
var recieved = sp.GetService<IDisposable>();
sp.Dispose();
// Assert
recieved.Should().NotBeNull();
A.CallTo(() => fake.Dispose()).MustHaveHappenedOnceExactly();
}
Upvotes: 4