2

So I am working on a simple project that utilizes an api layer, services layer (think business logic) and all the appropriate supporting layers around it. In the past I believe Web Api 2 requests would kick off the disposal hierarchy when the controller went out of scope (thus any services that were called from the api and were data members of the class, were disposed along with their subsequent repositories/dependencies).

In core, I can see where dispose is called from the controller if I do a simple method override that calls base.dispose(). However, it seems for my service to begin its disposal process I am stuck using the PerRequestLifetime scope of LightInject to get rid of the disposable resources. Is this just something different with core? Usually transients have given me the behavior I would expect (dispose calls for dependencies are made when controller.dispose() is called). Full disclosure the previous work I have done used the Unity IoC container.

I believe ultimately the result is the same as overridding the controller dispose method to call service.dispose(), but I am just surprised by the behavior of LightInject transients in the core context.

Here is my repository with example code https://github.com/napalm684/ReciPiBookCore .

Of primary focus here of course is the UnitOfMeasureController and the UnitOfMeasureService. The DI layer (specifically https://github.com/napalm684/ReciPiBookCore/blob/master/src/ReciPiBook.Di/ServiceContainerExtensions.cs) is where you will find the LightInject registration work for the service.

Registration

container.Register<IUnitOfMeasureService, UnitOfMeasureService>(new PerRequestLifeTime());

Controller

[Route("api/[controller]")]
public class UnitOfMeasureController : Controller
{
    private readonly IUnitOfMeasureService _unitOfMeasureService;

    public UnitOfMeasureController(IUnitOfMeasureService unitOfMeasureService)
    {
        _unitOfMeasureService = unitOfMeasureService;
    }

    [HttpGet]
    [Route("{id:int}")]
    public string Get(int id)
    {
        return _unitOfMeasureService.Get(id).Description;
    }
}

Service

public class UnitOfMeasureService : IUnitOfMeasureService
{
        private readonly IRepository<Entities.UnitOfMeasure> _repository;
        private bool _disposed = false;

        public UnitOfMeasureService(IRepository<Entities.UnitOfMeasure> repository)
        {
            _repository = repository;
        }

        public Dtos.UnitOfMeasure Get(int id)
        {
            return _repository.Get(id).AsUnitOfMeasure();
        }

        protected virtual void Dispose(bool disposing)
        {
            if (_disposed) return;

            if (disposing)
                _repository.Dispose();

            _disposed = true;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
}
Shawn
  • 869
  • 1
  • 9
  • 27
  • I'm pretty sure its the same behavior as Web Api 2. Controllers were created and disposed of per request, the same is for Controllers in Core. Unless you are doing multiple resolutions of a service, a Transient lifetime is going to be the same as request lifetime pretty much. – Mike_G Nov 01 '16 at 13:41
  • In this case it doesn't seem to hold true if you run my solution in debug you will see when UnitOfMeasureController is disposed it never calls Dispose on UnitOfMeasureService as a transient. Obviously I don't want that memory to leak. – Shawn Nov 01 '16 at 14:03

0 Answers0