2016-02-29 65 views
0

我想了解IoC並確定它是否適合這種特定場景。我有以下代碼:Unity:通過其構造函數依賴解決接口實現

public class List { ... } 
public class Form { ... } 

public interface IService { ... } 

public class ListService : IService { 
    public ListService(List list) { } 
} 

public class FormService : IService { 
    public FormService(Form form) { } 
} 

class Program { 
    static void Main(string[] args) { 
     IUnityContainer container = new UnityContainer(); 
     container.RegisterType<IService, ListService>(new InjectionConstructor(typeof(List))); 
     container.RegisterType<IService, FormService>(new InjectionConstructor(typeof(Form))); 

     IService formService = container.Resolve<IService>(new DependencyOverride<Form>(new Form())); 
     IService listService = container.Resolve<IService>(new DependencyOverride<List>(new List())); 
    } 
} 

上面明顯的代碼不起作用,因爲IService第二登記覆蓋的第一個。但意圖是能夠使用其構造函數依賴關係來解決實例IService。我意識到這不是一個典型的IoC場景,而是一個混合工廠/ IoC,我想知道是否可以連接統一以適應這種情況。

結論編輯:
實際問題比上面的例子更復雜。 ServiceDefinition對象(List,Form)來自WCF Web服務。從那裏,系統將構建IService實例和其他對象鏈,最終導致一組WPF視圖和視圖模型。在構造函數中明確定義了一些依賴項,其他依賴項則使用接口作爲構造函數參數。

我的第一種方法是使用命名註冊與InjectionConstructor \ ResolvedParameter相結合。但它很快變得相當複雜。根據蘭迪的建議,我開始考慮使用Unity的汽車工廠。這裏是技術上的related post。這是我得到的代碼片段

public class Form { } 
public class FormService : IService{ 
    [InjectionConstructor] 
    public FormService(Func<string, Form> func, string name):this(func(name)) { } 
    public FormService(Form form) { } 
} 
public class FormDataViewModel { 
    public FormDataViewModel(FormService svc) { } 
} 
public interface IService { } 
class Program { 
    static Form GetForm(string name) { 
     //wcf call 
     return new Form(); 
    } 
    static void Main(string[] args) { 
     IUnityContainer container = new UnityContainer(); 
     container.RegisterInstance<Func<string, Form>>(GetForm); 
     container.RegisterType<IService, FormService>("form"); 
     FormDataViewModel vm = container.Resolve<FormDataViewModel>(new DependencyOverride<string>("/system/form/test")); 
    } 
} 

上面的代碼是一個意義上的混合動力廠\ IoC機制。感謝Unity的靈活性。純粹的IoC不適合我的許多場景。

+1

我不認爲這是可能的。爲什麼不簡單地給每個註冊名稱?請注意,您可以在沒有容器的情況下執行IOC。這被稱爲[Pure DI](http://blog.ploeh.dk/2014/06/10/pure-di/)。 –

回答

2

使用Unity,有多個註冊與接口關聯的唯一方式(開箱即用)是使用命名註冊。

在您所描述的情況下(實際情況可能會更復雜),似乎並不是這個問題。我想你會以某種方式知道你想要什麼類型的服務(Form vs. List)。

如果情景比較複雜,那麼你幾乎可以總是達到你想要的工廠(工廠在問題中提到,所以它似乎適合)。有些工廠示例請參見Automatic Factories

基本上,IService的所有適用實例都可以注入工廠,並且工廠可以在運行時確定(並根據適用的任何標準)什麼是合適的實例返回。您甚至可以注入Func<IService>而不是IService以推遲創建對象。