ASP.NET MVC,Unity和IDisposable

SA.*_*SA. 6 c# dependency-injection idisposable unity-container asp.net-mvc-4

我正在使用ASP.Net MVC 4,EF和Unity for DI.还使用UnitOfWork模式.试图找出实现这一目标的最佳方法.我有如下代码.我遇到的问题是Business和Repository层中的Dispose()现在永远不会被调用,只有两个中的Destructor被调用,所以对象似乎永远不会被处理掉.请回答以下问题

  1. 我是否真的需要Business和Repository层中的IDisposable实现(如果Unity已经在处理它)

  2. 我应该怎么做才能调用Dispose()(我应该将它添加到Controller中还是Dispose所有其他对象或使用某些特定的LifeTime管理器)

  3. 我是否应该使用每个的Singleton实例,或者将它放在每个请求中,就像它在Web环境中一样.

的Global.asax.cs:

private static IUnityContainer _unityContainer;

protected void Application_Start()
{
   _unityContainer = UnityBootstrapper.SetupUnity();
   _unityContainer.RegisterType<IController, ProductController>("Product");  
   DependencyResolver.SetResolver(new Microsoft.Practices.Unity.Mvc.UnityDependencyResolver(_unityContainer));
}  
Run Code Online (Sandbox Code Playgroud)

UnityBootstrapper.cs:

public class UnityBootstrapper
{
    public static IUnityContainer SetupUnity()
    {
        UnityContainer container = new UnityContainer();
        container.RegisterType<IProductDbContext, ProductDbContext>()
                 .RegisterType<IUnitOfWork, UnitofWork>(new InjectionConstructor(new ResolvedParameter(typeof(IProductDbContext))))
                 .RegisterType<IProductRepository, ProductRepository>()
                 .RegisterType<IProductBusiness, ProductBusiness>();
    }
}
Run Code Online (Sandbox Code Playgroud)

ProductController.cs:

public class ProductController : ControllerBase
{
    private readonly IProductBusiness _productBusiness;        

    public ProductController(IProductBusiness productBusiness)
    {
        _productBusiness = productBusiness;
    }

    //No Dispose for this
}
Run Code Online (Sandbox Code Playgroud)

ProductBusiness.cs:

public class ProductBusiness : IProductBusiness, IDisposable
{
    private readonly IUnitOfWork _unitOfWork;
    private readonly IProductRepository _productRepository;
    public ProductBusiness(IUnitOfWork unitOfWork)
    {
        _unitOfWork = unitOfWork;
        _productRepository = _unitOfWork.ProductRepository;
    }

    public override void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected override void Dispose(bool disposing)
    {
        if (!_isDisposed)
        {
            if (disposing)
            {
                if (_productRepository != null) _productRepository.Dispose();
                if (_unitOfWork != null) _unitOfWork.Dispose();
            }

            _isDisposed = true;
         }
    }

    ~ProductBusiness()
    {
         Dispose(false);
    }
}
Run Code Online (Sandbox Code Playgroud)

ProductRepository.cs:

public class ProductRepository : IProductRepository, IDisposable
{
    private readonly IProductDbContext _context;

    public ProductRepository(IProductDbContext context)
    {
        if (context == null)
            throw new ArgumentNullException("context");

        _context = context;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!_isDisposed)
        {
            if (disposing)
            {
                if (_context != null) _context.Dispose();
            }

            _isDisposed = true;
        }
    }

    ~ProductRepository()
    {
        Dispose(false);
    }
}   
Run Code Online (Sandbox Code Playgroud)

she*_*nku 1

虽然 Unity将管理已注册类型的处置,但您仍然需要在 IOC 容器上调用 dispose,以便它为它们执行此操作。

从Application_End开始做应该没问题。

    protected void Application_End()
    {
        _unityContainer .Dispose();
    }
Run Code Online (Sandbox Code Playgroud)