我想知道我的上下文是如何处置的,或者是否完全处置了我的上下文!我知道我是垃圾收集器的外汇,以整理一切,但是有些东西只是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输入参数 - 这意味着它不会自动处置,您可以以某种自定义方式处理它。