2016-11-11 75 views
2

我想要什麼:解決對象A和對象A的內部,我想用同一個容器來解決對象C:IoC容器。注入容器

public static void Work() 
{ 
    IUnityContainer con = new UnityContainer(); 
    con.RegisterType<IA, A>(); 
    con.RegisterType<IB, B>(); 
    con.RegisterType<IC, C>(); 

    var a = con.Resolve<IA>(); 
} 


interface IA { } 
interface IB { } 
interface IC { } 

class A : IA 
{ 
    public A(IB b, IUnityContainer con) 
    { 
     for (int i = 0; i < 10; i++) 
     { 
      var c = con.Resolve<IC>(); 
     } 
    } 
} 

class B : IB { }; 
class C : IC { }; 

問題:在許多網站我看到注入容器是壞主意,但如何處於這種情況?

EDIT 1

服務定位器是一個反模式。因此,如果可以使用Service Locator和IoC Container,爲什麼它可以?

+1

我從你的問題缺少的是*你在這裏試圖解決什麼問題。爲什麼你需要多次解析'IC',爲什麼你需要在'A'的構造函數中做這個。你能否通過使用真實姓名來更具體地描述你的用例,並描述你在做什麼,爲什麼? – Steven

+0

@Steven我想在我的應用程序的許多地方使用容器。我的解決方案是到處注入該容器。我知道注入到處都是壞主意,但服務定位器被稱爲反模式和靜態類更糟糕。 –

+1

這是我清楚的部分。我不清楚的是你的具體用例。請詳細說明一個真實的例子,而不是像'A'和'IC'這樣的類。 – Steven

回答

3

你不應該傳遞給你的類的直接引用,因爲這將使你的代碼依賴於使用的IOC容器(這裏是UnityContainer),並使得它對單元測試有點困難。

如果您的類A需要C的多個實例,您應該爲這種情況定義一個工廠並將該工廠的一個實例傳遞給您的類A.您的真實工廠可以引用UnityContainer。對於單元測試,您可以模擬接口並將模擬的實例傳遞給您的類A.

此代碼看起來像這樣。

public interface IClassICFactory 
{ 
    IC CreateInstance(); 
} 

public class ClassICUnityContainerFactory : IClassCFactory 
{ 
    private IUnityContainer _container; 

    public ClassICUnityContainerFactory(IUnityContainer container) 
    { 
     _container = container; 
    } 

    public IC CreateInstance() 
    { 
     return _container.Resolve<C>(); 
    } 
} 

class A : IA 
{ 
    public A(IB b, IClassICFactory factory) 
    { 
     for (int i = 0; i < 10; i++) 
     { 
      var c = factory.CreateInstance(); 
     } 
    } 
} 
0

雖然技術上有效,但它有點'容器',會導致大量的混淆。我爲處理這種事情的容器創建靜態工廠類。您通過容器解決的類實例應該只關心他們打算做什麼,而不是進一步解決其他實例。

+0

但是,如果您引用靜態工廠,它不會讓您注入模擬對象並且不再可測試。 –

+0

那是因爲靜態類是他們自己的實現。你不需要提供一個實例。只需在您的測試中訪問靜態類 –