2011-12-21 54 views
0

我一直使用Unity作爲IoC容器一段時間,並且找不到正確的解決方案來解決經常出現的問題。我需要創建AuditInsertLogWriter和AuditUpdateLogWriter的某些情況下取決於操作參數(它們實現IAuditOperationLogWriter接口),你可以在下面看到:Unity - 根據上下文解析正確的實例

public IAuditOperationLogWriter Create(Operation operation) 
{ 
    switch (operation) 
    { 
     case Operation.Insert: 
      return UnityContainer.Resolve<AuditInsertLogWriter>(); 
     case Operation.Update: 
      return UnityContainer.Resolve<AuditUpdateLogWriter>(); 
     default: 
      break; 
    } 
} 

的事情是,這些情況是複雜的,因爲他們自己的依賴創造。此外,我想在該工廠中刪除與Unity的依賴關係。所以,我的問題是:我如何才能實現Unity根據某些上下文來解析創建的正確類型?

+1

在這裏看到一個籠統的回答到什麼是真正的問題,一般類型:http://stackoverflow.com/questions/1943576/is-there-a-pattern-for-initializing-objects-created-通過一個容器/ 1945023#1945023 – 2011-12-22 12:22:32

回答

3

如果要刪除工廠對容器的依賴關係,則必須提前連接所有依賴關係。

一個優雅的方法是使用Unity對自動工廠的支持。

你可以定義你的工廠是這樣的:

public class AuditOperationLogWriterFactory 
{ 
    private Dictionary<Operation, Func<IAuditOperationLogWriter>> auditCreator = 
     new Dictionary<Operation, Func<IAuditOperationLogWriter>>(); 

    public AuditOperationLogWriterFactory(Func<AuditInsertLogWriter> insert, 
     Func<AuditUpdateLogWriter> update) 
    { 
     auditCreator[Operation.Insert] = insert; 
     auditCreator[Operation.Update] = update; 
    } 

    public IAuditOperationLogWriter Create(Operation operation) 
    { 
     if (auditCreator.ContainsKey(operation)) 
     { 
      return auditCreator[operation](); 
     } 

     return null; 
    } 
} 

然後你可以解決工廠和統一應當線了依賴和對象的創建推遲到運行時(根據上下文)。如果它們很複雜,則可能需要通過配置(配置文件,代碼或屬性)來提供幫助。

IUnityContainer container = new UnityContainer(); 

var factory = container.Resolve<AuditOperationLogWriterFactory>(); 

var logWriter = factory.Create(Operation.Insert); 
+0

我採取了類似的方法,但是你的想法看起來更好。我還沒有嘗試過(我將盡快完成)。所以,我不知道它是否可以工作,但我投了票,謝謝。 – lontivero 2011-12-22 05:10:32

+0

不錯的解決方案。我會放下字典。只有兩個選擇,它不會給你任何表現。一個簡單的開關或if-then-else至少是一樣快。 – 2011-12-22 06:57:18

+0

@ SebastianWeber:我同意你的觀點。我[之前](http://stackoverflow.com/revisions/8599174/1)有一個if-then-else但改變了它。我並不擔心這裏的性能,但如果你想添加一個新類型,那麼你不必改變if或switch語句。 – 2011-12-22 14:17:01

0

您可以使用註冊名稱註冊您的類型,這可能是您的操作名稱。解決時,使用適當的名稱,您將得到適當的註冊。

查看UnityContainer的註冊和解析方法的重載列表,並找到具有「name」參數的那些方法。這就是你要找的。

+1

這是一個有效的方法,但我不想在工廠類中引用容器(它不應該在那裏)。 – lontivero 2011-12-22 05:15:04