2014-02-10 62 views
0

使用this通用存儲庫和EF6工作單元框架,每當我完成一個工作單元操作時,我的控制器中的Dispose方法被調用兩次。爲什麼是這樣?我希望它只應該被調用一次。爲什麼在使用這個工作單元時Dispose被調用兩次?

這裏的設置:

引導程序類 - 建立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); 
    } 

} 

在閱讀另一篇文章中有人表示,由於他們使用統一的國際奧委會,那可以部署所有的uow s。難道Autofac正在調用第二個配置?這已經設置爲調用處理?

我認爲問題是與Autofac,所以我加了.ExternallyOwned(),telling Autofac that I'll take care of the disposal,但同樣的問題。

我認爲我可能錯誤地使用了_uow(uow/repository調用,並且存儲庫也在處理?),但在這裏不確定。

對此提出建議?

- 更新 -

後的兩個堆棧上運行的差異痕跡這裏的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。

+0

需要更多的信息,你怎麼知道你的'dispose'被調用兩次? – Turbot

+0

@Turbot - 我在'_db.Dispose();'處設置了一個斷點 - 每次操作它會被擊中兩次(將註釋添加到問題中)。 – ElHaix

+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方法的設計應該允許多次調用。如果任何這樣的方法不能被多次調用,我會感到驚訝。

相關問題