根据Simple Injector文档,我将为MVC应用程序实例化我的存储库对象:
container.RegisterPerWebRequest<IUserRepository, SqlUserRepository>();
container.RegisterPerWebRequest<IOrderRepository, SqlOrderRepository>();
但我刚刚发现文档也说明了:
与Simple Injector的默认行为相反,这些扩展方法确保处理已创建的服务(当此类实例实现IDisposable 时)。
https://simpleinjector.codeplex.com/wikipage?title=ObjectLifestyleManagement#PerWebRequest
问题:这是否意味着在使用RegisterPerWebRequest时,我的对象需要实现IDisposable,以便在Web请求结束时(即代码下方)处理?
附注:我相信使用WebRequestLifestyle,RegisterInitializer,RegisterForDisposal,还需要实现IDisposable的对象。
下面的示例代码(接口和实现)。
public interface IUserRepository : IDisposable
{
...
}
public class SqlUserRepository : IUserRepository, IDisposable
{
...
...
...
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);
}
}
答案 0 :(得分:5)
这里有一些注意事项,您似乎在这里实现了完整的配置模式,但是在制作SqlUserRepository
sealed
时可以简化这一点。这允许您执行以下操作:
public sealed class SqlUserRepository : IUserRepository, IDisposable
{
public void Dispose()
{
_context.Dispose();
}
}
由于SqlUserRepository
已被封存,因此无法从中获取,因此:
SuppressFinalize
,因为只有在有最终确定方法时才需要这样做,但由于您没有实施,因此您确定没有派生类型,你不需要打电话。也没有必要使用disposed
标志,因为您将dispose委托给_context
,但它应该能够多次调用dispose;这是IDisposable
合同中定义的。
此外,如果您将该上下文对象注入SqlUserRepository
的构造函数中,则根本不需要在SqlUserRepository
上实现一次性。您只需要使用Web请求生活方式注册该上下文,Simple Injector将为您处理该内容。
答案 1 :(得分:4)
披露:我没有使用SimpleInjector。
从我从阅读中收集到的内容,不,您不需要实施IDisposable
。
它的含义是,默认情况下,注册的对象不会被丢弃。也就是说,如果您通过非Web请求注册对象,SimpleInjector将不会尝试调用Dispose()
。
但是,使用RegisterPerWebRequest()
表示如果对象为Dispose()
,则会调用IDisposable
,除非您另行指定。