C# 使用依赖注入时,我的数据库连接是否得到处理?

C# 使用依赖注入时,我的数据库连接是否得到处理?,c#,entity-framework,dependency-injection,autofac,C#,Entity Framework,Dependency Injection,Autofac,我想知道我的上下文是如何被处理的,或者它是否正在被处理! 我知道我会让垃圾收集者把所有的东西都清理干净,但是有一件事一直困扰着我 我需要为单元测试注入conext 问题是我的代码使数据库连接保持打开状态 我的服务是这样的,随着上下文被传递到构造函数中,依赖注入由autofac处理 公共类FooService:IFooService { 私有只读上下文; 公共服务(上下文) { this.context=上下文; } 公共IEnumerable GetAll() { 返回context.Foo.T

我想知道我的上下文是如何被处理的,或者它是否正在被处理! 我知道我会让垃圾收集者把所有的东西都清理干净,但是有一件事一直困扰着我

我需要为单元测试注入conext

问题是我的代码使数据库连接保持打开状态

我的服务是这样的,随着上下文被传递到构造函数中,依赖注入由autofac处理

公共类FooService:IFooService
{
私有只读上下文;
公共服务(上下文)
{
this.context=上下文;
}
公共IEnumerable GetAll()
{
返回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);
    }
}
公共类FooService:IFooService,IDisposable
{
私有只读上下文;
公共服务(上下文)
{
this.context=上下文;
}
公共IEnumerable GetAll()
{
返回context.Foo.ToList();
}
私有布尔=假;
受保护的虚拟void Dispose(bool disposing)
{
如果(!this.disposed)
{
如果(处置)
{
context.Dispose();
}
}
这是真的;
}
公共空间处置()
{
处置(真实);
总干事(本);
}
}

小心上下文和服务的生命周期的混合。我认为服务类似于单例,但上下文不应超过每个请求。您还可以让多个线程访问同一个上下文对象,这将导致连接状态错误

在代码中,当释放autofac容器时,上下文将被释放

您应该创建一些上下文工厂,或直接在using block中使用上下文:

公共类FooService:IFooService
{
公共服务()
{
}
公共IEnumerable GetAll()
{
使用(var context=new context())
{
返回context.Foo.ToList();
}
}
}
1)您不应该在
上下文被注入(died)时手动处理它,从技术上讲,它不属于类的实例,也就是说,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) 如果您希望对数据服务的生命周期有更多的控制权,并自己处理它们,您可以使用
Owned
例如
Owned
作为您的.ctor输入参数,这意味着它不会被自动处理,您可以以您认为合适的自定义方式处理它

我会更新我的帖子说,我需要为单元测试注入conext。在您的代码中,您使用的是与参数相同的实例。您可以将上下文注册为单独的对象
builder.RegisterType()
并且您不必将
与参数一起使用
定义。