依赖注入是我的数据库连接被处置



我想知道我的上下文是如何处置的,或者是否完全处置了我的上下文!我知道我是垃圾收集器的外汇,以整理一切,但是有些东西只是na了我的脑海。

我需要注入单位测试的偶像

任务是我的代码,留下了DB连接。

我的服务看起来像这样,并且上下文被传递到构造函数中,依赖性注入由AutoFac处理。

public class FooService : IFooService 
{
    private readonly Context context;
    public CountryService(Context context)
    {
           this.context = context;
    }
    public IEnumerable<Foo> GetAll()
    {
        return context.Foo.ToList();
    }
}

我的AutoFac设置看起来像

public class ServiceModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        // "ThisAssembly" means "any types in the same assembly as the module"
        builder
          .RegisterAssemblyTypes(ThisAssembly)
          .Where(t => t.Name.EndsWith("Service"))
          .WithParameter("context", new MyContext())
          .AsImplementedInterfaces();
    }
}

我已经在解决方案上看到了添加Idisposable

public class FooService : IFooService , IDisposable
{
    private readonly Context context;
    public CountryService(Context context)
    {
        this.context = context;
    }
    public IEnumerable<Foo> GetAll()
    {
        return context.Foo.ToList();
    }
    private bool disposed = false;
    protected virtual void Dispose(bool disposing)
    {
        if (!this.disposed)
        {
            if (disposing)
            {
                context.Dispose();
            }
        }
        this.disposed = true;
    }
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

提防混合上下文和服务的寿命。我想服务就像单身人士,但上下文不应超过要求。您还可以最终让多个线程访问相同的上下文对象,这将导致连接状态错误。

在您的代码中处置AutoFac容器时,上下文将被处置。

您应该创建某些上下文工厂或直接在使用块中使用上下文:

public class FooService : IFooService 
{
    public CountryService()
    {
    }
    public IEnumerable<Foo> GetAll()
    {
        using (var context = new Context())
        {
            return context.Foo.ToList();
        }
    }
}

1)您不应在注入(di-ed)时手动处置 Context,而且从技术上讲,它不是拥有的。AutoFac管理其处置,因为它可以同时将其注入其他地方,这一切都取决于所有这些对象的寿命(即AutoFac是唯一真正知道何时最好地处置它的人)。

2)AUTOFAC通过使用示波器,寿命自动处置。在您的情况下,这意味着您的容器,根部范围,当一个范围范围时,所有的都将被处置。所以不,你不应该担心。
因此,简而言之,AutoFac提供了一种用于管理对象生命和处置的替代机制。实际上它非常整洁,您真的可以确保事情会以有组织的方式被处置。

通过单位测试我通常喜欢做的事情,不是必需的,但可以使我更多地控制事物...

// within your unit test
using (var scope = Container.BeginLifetimeScope())
{
    // and now resolve your services using the 'scope' (instead of the Container)
}  

3)如果您希望对DI -ED服务的寿命有更多的控制权并亲自处置 - 您可以使用Owned<>,例如Owned<Context>作为您的.CTOR输入参数 - 这意味着它不会自动处置,您可以以某种自定义方式处理它。

最新更新