MVC Simple Injector和RegisterPerWebRequest

时间:2014-09-18 01:30:19

标签: asp.net-mvc simple-injector

根据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);
    }
}

2 个答案:

答案 0 :(得分:5)

这里有一些注意事项,您似乎在这里实现了完整的配置模式,但是在制作SqlUserRepository sealed时可以简化这一点。这允许您执行以下操作:

public sealed class SqlUserRepository : IUserRepository, IDisposable
{
    public void Dispose()
    {
        _context.Dispose();
    }
}

由于SqlUserRepository已被封存,因此无法从中获取,因此:

  • 不需要虚拟保护的Dispose(bool)方法。
  • 无需拨打SuppressFinalize,因为只有在有最终确定方法时才需要这样做,但由于您没有实施,因此您确定没有派生类型,你不需要打电话。

也没有必要使用disposed标志,因为您将dispose委托给_context,但它应该能够多次调用dispose;这是IDisposable合同中定义的。

此外,如果您将该上下文对象注入SqlUserRepository的构造函数中,则根本不需要在SqlUserRepository上实现一次性。您只需要使用Web请求生活方式注册该上下文,Simple Injector将为您处理该内容。

答案 1 :(得分:4)

披露:我没有使用SimpleInjector。

从我从阅读中收集到的内容,不,您不需要实施IDisposable

它的含义是,默认情况下,注册的对象不会被丢弃。也就是说,如果您通过非Web请求注册对象,SimpleInjector将不会尝试调用Dispose()

但是,使用RegisterPerWebRequest()表示如果对象为Dispose(),则会调用IDisposable,除非您另行指定。