2014-01-06 42 views
1

我正在構建ASP.NET MVC應用程序,並首次使用Unity實現依賴注入。對於一個特定的接口,我已經註冊了多個類型,就像這樣:解決應用程序啓動之外的Unity依賴關係,在庫中

container.RegisterType<ICache, AppfabricCache>("AppfabricCache", new ContainerControlledLifetimeManager()); 
container.RegisterType<ICache, MemoryCache>("MemoryCache", new ContainerControlledLifetimeManager()); 

我現在需要做哪一個使用基於一個CacheType枚舉的決定。

我可以像Sixeyed.Caching項目中那樣實現它,但它使您可以在不同的地方註冊類型。此外,您現在還有一個容器周圍的靜態包裝,它並不乾淨。

public static class Cache 
{ 
    private static readonly IUnityContainer _container; 
    static Cache() 
    { 
     _container = new UnityContainer(); 
     _container.RegisterType<ICache, MemoryCache>("MemoryCache", new ContainerControlledLifetimeManager()); 
    } 

    public static ICache Get(CacheType cacheType) 
    { 
     ICache cache = new NullCache(); 
     switch(cacheType) 
     { 
      case CacheType.Memory: 
       cache = _container.Resolve<ICache>("MemoryCache"); 
       break; 
      ... 
      ... 
     } 
    } 
} 

如何在我的應用程序中從其他庫項目中獲取容器?或者說,我該如何從圖書館做這種決議?或者,也許我不應該?

blog post表示將容器放在應用程序入口點之外不是一個好主意,這聽起來正確。什麼是正確的方法來做到這一點?

+0

如何以及何時需要在ICache實現之間選擇/切換?這是基於web.config設置嗎?基於一些程序邏輯? – Steven

+0

@Steven程序邏輯 - 一個進程內緩存(如Level 1)和一個進程外緩存(Level 2)。但是,嘿,即使我只有一種類型的緩存(很可能),我想在不同的地方使用它。我不想在所有我想要使用緩存的地方通過構造函數傳遞ICache。 – Narayana

+0

爲什麼你不想使用構造函數注入?如果你需要在很多地方注入,你可能違反了單一責任原則。緩存是一個橫切關注點,最好使用攔截或裝飾添加。 – Steven

回答

2

正如@ploeh所示,容器不應該在應用程序根目錄之外被知道。
系統可根據運行時間值的實現,你應該使用工廠

public class CacheFactory : ICacheFactory 
{ 
    private readonly IUnityContainer _container; 

    public CacheFactory(IUnityContainer container) 
    { 
     if (container == null) 
      throw new ArgumentNullException("container"); 

     _container = container; 
    } 

    public ICache Get(CacheType cacheType) 
    { 
     // implementation as in your post 
    } 
} 

public class SomethingUsingTheCache 
{ 
    private readonly ICacheFactory _cacheFactory; 

    public SomethingUsingTheCache(ICacheFactory cacheFactory) 
    { 
     if (cacheFactory == null) 
      throw new ArgumentNullException("cacheFactory"); 

     _cacheFactory = cacheFactory; 
    } 

    public void DoStuff() 
    { 
     // get from config or wherever 
     CacheType cacheType = CacheType.Memory; 

     ICache cache = _cacheFactory.Get(cacheType); 
     // do something with cache 
    } 
} 

工廠放在應用程序根任何其他類使用工廠並有沒有概念的容器

+0

謝謝,這有幫助。雖然我無法使用構造函數注入,因爲我通過PostSharp AOP使用Cache。 http://codereview.stackexchange.com/questions/20341/inject-dependency-into-postsharp-aspect幫助我解決了這個問題。 – Narayana

相關問題