6

我正在使用ASP.Net MVC 4,EF和Unity的DI。也使用UnitOfWork模式。試圖找出實現這一點的最佳方式。我有如下的代碼。 我遇到的問題是Dispose()在業務和存儲庫層現在不會被調用,只有在兩個析構函數被調用,所以對象似乎永遠不會被處置。 請回答下列ASP.NET MVC,Unity和IDisposable

  1. 我真的需要在業務了IDisposable執行和庫層(如果統一已經照顧吧))稱爲

  2. 我應該怎麼做才能得到的Dispose( (我應該把它添加到控制器也和處置所有其他對象,或者使用一些特定的生命期管理器)

  3. 我是否應該使用每個的單一實例或處置其在每個請求,因爲它是在網絡環境中。

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

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

ProductController.cs:

public class ProductController : ControllerBase 
{ 
    private readonly IProductBusiness _productBusiness;   

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

    //No Dispose for this 
} 

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

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

謝謝大家對於快速響應 –

+0

SA,歡迎來到StackOverflow。按照這個社區的慣例,你可以通過投票答案來說「謝謝」。然後將最有用的答案標記爲已接受的答案。請查看常見問題解答部分,瞭解有關投票的最新信息:http://stackoverflow.com/help/why-vote – trailmax

回答

1

雖然統一will manage disposing of your registered類型,你還是打電話給你的IOC容器的配置,以便它爲他們。

從Application_End開始,它應該沒問題。

protected void Application_End() 
    { 
     _unityContainer .Dispose(); 
    } 
1

我相信,如果你設置了正確的LifetimeManager則沒有,你並不需要實現IDisposable的團結會處理你的對象的處置。這解釋了不同類型的終身管理員http://msdn.microsoft.com/en-us/library/ff660872(v=pandp.20).aspx

就我個人而言,我並沒有使用單例,只是讓對象被創建,然後在每個請求中處理。

0

因爲IDisposable的主要目的是清理非託管資源,所以您不需要在這些類上使用IDisposable。看看這些:

http://msdn.microsoft.com/en-us/library/system.idisposable(v=vs.110).aspx

Proper use of the IDisposable interface

使用您的容器單件模式,如果您使用的容器中,在服務定位的方式可以是有益的。但是,還有其他(可以說是更好的)方式來使用Unity或其他DI/IoC容器。那裏有幾個bootstrappers。例如:

https://www.nuget.org/packages/Unity.Mvc/

2

你並不真的需要處置的對象,除非你做的處置過程中一些具體的事情。 DI容器爲您處理物體壽命。

有時候UoW的實施涉及保存處置的變化。儘量避免這一點。但如果這是不可避免的,你可以實現工廠:

public interface IUnitOfWorkFactory 
{ 
    IUnitOfWork Create(); 
} 

public class UnitOfWorkFactory : IUnitOfWorkFactory 
{ 
    public IUnitOfWork Create() 
    { 
     return new UnitOfWork(); 
    } 
} 

public class UnitOfWork : IUnitOfWork, IDisposable 
{ 
    // other implementation 


    public void Dispose() 
    { 
     context.SaveChanges(); 
    } 
} 

,然後消費者就做這樣的事情:大約一次性對象

public MyController(IUnitOfWorkFactory workFactory) 
{ 
    this.workFactory = workFactory; 
} 

public ActionResult DoSomething() 
{ 
    using(var uow = workFactory.Create()) 
    { 
     //do work 
    } 
} 

This DI book chapter會談。