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

时间:2017-03-13 11:48:43

标签: c# entity-framework dependency-injection autofac

我想知道我的背景是如何被处置的,或者它是否被处置掉了! 我知道我会把垃圾收集器放在一边来整理所有东西,但有些东西只是在我心中唠叨。

我需要注入conext进行单元测试

The Questsion,我的代码是否打开了数据库连接。

我的服务看起来像这样,上下文传递给构造函数,依赖注入由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);
    }
}

2 个答案:

答案 0 :(得分:0)

注意混合上下文和服务的生命周期。我认为服务就像一个单身人士,但上下文应该不超过每个请求。您也可能最终让多个线程访问相同的上下文对象,这将导致连接状态错误。

在代码中,当处理autofac容器时,将处理上下文。

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

public class FooService : IFooService 
{
    public CountryService()
    {
    }

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

答案 1 :(得分:0)

1)您不应该在注入(DI-ed)时手动处理OR,从技术上讲,它不是拥有通过你的班级实例,即Autofac管理它的处理,因为它可以同时注入其他地方,这一切都取决于所有这些对象的生命周期(即Autofac是唯一一个实际知道何时最好处理它。)

2)Autofac通过使用范围,生命周期自动处理。在你的情况下,这意味着你的容器,根范围,当一个超出范围时,所有将被处置。所以不,你不应该担心它 因此,简而言之,Autofac类型提供了一种替代机制来管理对象的生命周期和处理。而且它实际上非常整洁,你可以确定事情会以有组织的方式处理。

通过单元测试我通常喜欢做的事情,没有必要,但让我对事物有了更多的控制......

Context

3)如果您希望更多地控制DI-ed服务的生命周期并自行处理它们 - 您可以使用// within your unit test using (var scope = Container.BeginLifetimeScope()) { // and now resolve your services using the 'scope' (instead of the Container) } ,例如Owned<>作为您的.ctor输入参数 - 这意味着它不会被自动处理,您可以以您认为合适的某种自定义方式处理它。