2011-07-25 59 views
2

望着這answer on SO,我有點在下面的「原則」困惑:依賴注入 - 正確的地方注入

應用好萊塢原則

好萊塢原則DI方面說:不要撥打DI Container,它會給你打電話。

千萬不要直接通過調用 代碼中的容器來請求依賴關係。通過使用構造器注入隱式地詢問它。

但是如果我在我的DAL的存儲庫類,我想這種情況下提供給當TCP/IP客戶端連接其上創建一個對象?我應該在什麼地方進行注射?

現在,我有這樣的事情:

// gets created when a new TCP/IP client is connected 
class Worker 
{ 
    private readonly IClient client; 
    public Worker(IClient client) 
    { 
     // get the repository 
     var repo = IoC.GetInstance<IClientMessagesRepo>(); 

     // create an object which will parse messages 
     var parser = new MessageParser(client); 

     // create an object which will save them to repo 
     var logger = new MessageLogger(parser, repo); 
    } 
} 

我當我的應用程序啓動明顯不能創建實例。那麼我在哪裏注入回購?

非常感謝!

+0

當應用程序被啓動爲什麼不能創建IClientMessageRepo實例?從給出的代碼,它遠不是'明顯的'... –

+0

你可能也想引用這個答案:http://stackoverflow.com/questions/1410719/design-where-should-objects-be-registered-when -using-windsor/1410738#1410738 –

+0

@Mark:不,對不起,我的意思是,我不能要求容器在開始時創建* Worker *實例。我*可以*創建回購實例,然後傳遞它,但我使用一個回購每個實體,所以我覺得傳遞一堆比使用容器來根據需要獲取它們更復雜。 – doe

回答

1

您應該努力只呼叫IoC.GetInstance()一次。

既然你不能在啓動時創建的工人,你應該建立WorkerFactory並有DI容器注入的依賴成:

public class WorkerFactory 
{ 
    private readonly IClientMessagesRepo clientMessagesRepo; 
    public WorkerFactory(IClientMessagesRepo clientMessagesRepo) 
    { 
     this.clientMessagesRepo = clientMessagesRepo; 
    } 

    public Worker Create(IClient client) 
    { 
     return new Worker(client, clientMessagesRepo); 
    } 
} 
0

移動IClientMessagesRepo到您的構造函數的參數:

public Worker(IClient client,IClientMessagesRepo clientMessagesRepo) 

現在當然這只是把問題移到了一下,到創建工人的地步。當然,有時需要調用IoC容器。但在這些情況下,我寧願傳入容器中的參數,而不是從靜態屬性中訪問它。或者使用某種工廠。

+0

但我該如何解決這種類型如果只有repo界面在我的IoC上註冊?我正在使用(或更好的,濫用)StructureMap。 (並將容器作爲參數傳遞是另一種違反「最佳實踐」的行爲) – doe

0

在有你的論點IClientMessagesRepo,並讓國際奧委會填補你:

public Worker(IClient client, IClientMessagesRepo repo)  
{ 
    [...] 
} 

很顯然,你的構造應該做一點不僅僅能創建幾個局部變量,但你的想法。

0

據我所知你在IOC容器中有儲存庫,但沒有IClient。假設你有訪問的時候你創建工人階級IOC容器,並假設你正在使用StructureMap你可以寫:

IClient concreteClient = ...; 
worker = container.Using<IClient>(concreteClient).GetInstance<Worker>(); 

這樣,你告訴StructureMap使用特定IClient實例,但獲得存儲庫中的其他依賴項。

注意:自從我上次使用StructureMap以來有一段時間,所以也許代碼不是100%正確的,但概念在那裏,您可以在創建組件時提供具體的依賴關係。