简体   繁体   English

来自 DI 容器.Net Core 的实现工厂方法中的对象

[英]Are objects from an implementation factory method disposed by the DI container .Net Core

When I register an implementation of an interface with an explicit implementationFactory, like this:当我使用显式 implementationFactory 注册接口的实现时,如下所示:

services.AddTransient<IDbConnection>(_ => new SqlConnection(connectionString));

The implementation is initialized when requested and disposed when out of scope by the DI container.该实现在请求时被初始化,并在 DI 容器超出 scope 时被释放。

But will the SqlConnection also be disposed by the DI container when I do something like this:但是当我执行以下操作时,DI 容器是否也会处理 SqlConnection:

services.AddTransient<IRepository>(_ => new Repository(new SqlConnection(connectionString)));

The intellisense isn't warning me about the undisposed object that implements IDisposable, but I don't think that's right.智能感知并没有警告我关于实现 IDisposable 的未处理的 object,但我认为这是不对的。

No, container will not dispose in second case, because it does not know anything about this manually created instance:不,容器不会在第二种情况下处理,因为它对这个手动创建的实例一无所知:

class MyDisposable : IDisposable
{
    public bool Disposed { get; private set; }
    public void Dispose()
    {
        Disposed = true;
    }
}

class Container
{
    public Container(MyDisposable d)
    {
        Disposable = d;
    }
    public MyDisposable Disposable { get; private set; }
}

var col = new ServiceCollection();
col.AddTransient<MyDisposable>(_ => new MyDisposable());
col.AddTransient<Container>(s => new Container(new MyDisposable()));

Container container;
MyDisposable disposable;
using(var scope = col.BuildServiceProvider().CreateScope())
{
    container = scope.ServiceProvider.GetRequiredService<Container>();
    disposable = scope.ServiceProvider.GetRequiredService<MyDisposable>();
}
Console.WriteLine(disposable.Disposed); // true
Console.WriteLine(container.Disposable.Disposed); // false

But if you change second registration to:但是,如果您将第二次注册更改为:

col.AddTransient<Container>(s => new Container(s.GetRequiredService<MyDisposable>()));

both MyDisposable 's will be disposed.两个MyDisposable都将被处置。

Using [Autofac][1] , for example you can resolve current lifetime scope and schedule manually created instance for disposal when this scope ends:例如,使用[Autofac][1]可以解析当前生命周期 scope 并安排手动创建的实例以在此 scope 结束时进行处理:

var builder = new ContainerBuilder();
builder.Register(_ => new MyDisposable()).InstancePerDependency();
builder.Register(ctx => 
{
    var scope = ctx.Resolve<ILifetimeScope>();
    var dep = new MyDisposable();
    scope.Disposer.AddInstanceForDisposal(dep);
    return new Container(dep);
})
.InstancePerDependency();

Container container;
MyDisposable disposable;
using(var scope = builder.Build().BeginLifetimeScope())
{
    container = scope.Resolve<Container>();
    disposable = scope.Resolve<MyDisposable>();
}

Console.WriteLine(disposable.Disposed); // true
Console.WriteLine(container.Disposable.Disposed);  // true

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM