Question

Using this generic repository and unit of work framework with EF6, whenever I complete a unit of work operation, the Dispose method in my controller is called twice. Why is this? I would expect that it should only be called once.

Here's the setup:

Bootstrapper class - setting up 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();

Controller:

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

}

In reading another post someone indicated that since they were using Unity for IoC, that could dispose all uows. Could it be that Autofac is calling the second dispose? Is this already setup to call dispose?

I thought the problem was with Autofac, so I added .ExternallyOwned(), telling Autofac that I'll take care of the disposal, but same issue.

I think that I may be using the _uow incorrectly (uow/repository call, and the repository is also disposing??), but not sure here.

Suggestions?

-- UPDATE --

After running a diff on the two stack traces here's the 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

The last two lines are the ones in the second call, but no reference to Autofac.

Was it helpful?

Solution

The namespace System.Web.Http.Tracing is for ASP.NET Web API tracing,

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

Thus, the second call to Dispose seems to be triggered by the trace writer, not Autofac,

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

I think by fully disabling tracing you should be able to suppress the second call. But generally speaking, Dispose methods should be designed in a way that allows multiple calls. I will be surprised if any of such methods cannot be called multiple times.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top