2014-02-10 3 views
0

Используя this общий репозиторий и блок работы с EF6, всякий раз, когда я завершаю единицу работы, метод Dispose в моем контроллере вызывается дважды. Почему это? Я бы ожидал, что его нужно вызывать только один раз.Почему 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 для IoC , которые могли бы распоряжаться всеми uow с. Может ли быть, что Autofac вызывает вторую утилиту? Это уже настроено для вызова dispose?

Я думал, что проблема была с Autofac, поэтому я добавил .ExternallyOwned(), telling Autofac that I'll take care of the disposal, но такой же вопрос.

Я думаю, что я могу неправильно использовать _uow (вызов uow/repository и репозиторий также удаляется?), Но не уверен здесь.

Предложения?

- ОБНОВЛЕНИЕ -

После запуска диф на два стека прослеживает вот разница:

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 для отслеживания Web API ASP.NET,

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 должны быть разработаны таким образом, чтобы допускать множественные вызовы. Я буду удивлен, если какой-либо из таких методов не может быть вызван несколько раз.