为什么在使用这个工作单元时Dispose被调用两次?

时间:2014-02-10 01:06:48

标签: c# repository-pattern entity-framework-6 unit-of-work

在EF6中使用this通用存储库和工作单元框架,每当我完成一个工作单元操作时,我的控制器中的Dispose方法被调用两次。为什么是这样?我希望它只能被调用一次。

以下是设置:

Bootstrapper类 - 设置Autofac IoC:

        builder.RegisterType<ProjectV001Context>().As<IDataContext>().InstancePerHttpRequest();

        // removed the repository registry as I'm using the uow
        //builder.RegisterType<Repository<ContentType>>().As<IRepository<ContentType>>().InstancePerHttpRequest();

        builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerHttpRequest();

控制器:

public class ContentTypesController : ODataController, IContentTypesController
{
    private ProjectV001Context _db = new ProjectV001Context();
    private readonly IUnitOfWork _uow;

    public ContentTypesController(IUnitOfWork unitOfWork)
    {
        _uow = unitOfWork;
    }

    // GET odata/ContentTypes
    [Queryable]
    public virtual IEnumerable<ContentTypeDTO> Get(ODataQueryOptions<ContentType> options)
    {
        var userId = 102;   // mock

        try
        {
            var result = options.ApplyTo(_uow.Repository<ContentType>().Query().Get()
                .Where(u => u.UserId == userId)
                .OrderBy(o => o.Description)).Cast<ContentType>();

            IQueryable<ContentTypeDTO> dto = result.Project().To<ContentTypeDTO>();

            return dto;
        }
        catch (Exception ex)
        {
            throw ex;
        }

    }


    protected override void Dispose(bool disposing)
    {
        if (disposing)   
        {
            _db.Dispose();    // <-- set breakpoint here - hit twice per operation
        }
        base.Dispose(disposing);
    }

}

在阅读其他帖子时,有人表示由于他们使用Unity for IoC,因此可以处置所有uow个。可能是Autofac正在调用第二次处理吗?这已经设置为调用dispose?

我认为问题出在Autofac上,所以我添加了.ExternallyOwned()telling Autofac that I'll take care of the disposal,但同样的问题。

我认为我可能错误地使用了_uow(uow / repository调用,并且存储库也在处理??),但在此不确定。

建议?

- 更新 -

在两个堆栈跟踪上运行diff后,这里是diff:

3       -   Autofac.dll!Autofac.Core.Disposer.Dispose(bool disposing)   Unknown
4       -   Autofac.dll!Autofac.Util.Disposable.Dispose()   Unknown
5       -   Autofac.dll!Autofac.Core.Lifetime.LifetimeScope.Dispose(bool disposing) Unknown
6       -   Autofac.dll!Autofac.Util.Disposable.Dispose()   Unknown
7       -   Autofac.Integration.WebApi.dll!Autofac.Integration.WebApi.AutofacWebApiDependencyScope.Dispose(bool disposing)  Unknown
8       -   Autofac.Integration.WebApi.dll!Autofac.Integration.WebApi.AutofacWebApiDependencyScope.Dispose()    Unknown
3   +   System.Web.Http.dll!System.Web.Http.Tracing.ITraceWriterExtensions.TraceBeginEnd(System.Web.Http.Tracing.ITraceWriter traceWriter, System.Net.Http.HttpRequestMessage request, string category, System.Web.Http.Tracing.TraceLevel level, string operatorName, string operationName, System.Action<System.Web.Http.Tracing.TraceRecord> beginTrace, System.Action execute, System.Action<System.Web.Http.Tracing.TraceRecord> endTrace, System.Action<System.Web.Http.Tracing.TraceRecord> errorTrace)  Unknown
4   +   System.Web.Http.dll!System.Web.Http.Tracing.Tracers.HttpControllerTracer.System.IDisposable.Dispose()   Unknown

最后两行是第二次调用中的行,但没有引用Autofac。

1 个答案:

答案 0 :(得分:2)

名称空间System.Web.Http.Tracing用于ASP.NET Web API跟踪,

http://msdn.microsoft.com/en-us/library/system.web.http.tracing(v=vs.118).aspx

因此,对Dispose的第二次调用似乎是由跟踪编写者触发的,而不是Autofac,

http://www.asp.net/web-api/overview/testing-and-debugging/tracing-in-aspnet-web-api

我认为通过完全禁用跟踪,你应该能够抑制第二次调用。但一般来说,Dispose方法应该以允许多次调用的方式设计。如果不能多次调用任何此类方法,我会感到惊讶。