2009-07-05 58 views
6

對不起,如果這是一個非常基本的問題,但它真的讓我很開心。我非常喜歡DI的想法,這對我的測試確實有幫助,但我想我已經碰到了一堵磚牆。所以,我有兩種類型:DI對象圖建築 - 分離邏輯和構造圖

Table 
TableManager 

現在的表對象都有這樣就可以構造:

Table(ITableCommandRunner tableRunner, 
     IQueryProvider queryProvider, 
     IDataReader reader, 
     string Name) 

現在的表對象幾乎只使用這些對象,以便以下是你要求的規則你需要什麼我將它們傳入。現在我的TableManager對象用於打開和關閉等表。它唯一需要的是一個ITableCommandRunner,所以我在構造函數中傳遞它。

TableManager(ITableCommandRunner tablrunner) 

好這很好,但在TableManager.OpenTable命令我必須呼籲ITableCommandRunner打開表條命令,然後建立一個新的表對象傳回。

public ITable OpenTable(string tableName) 
    { 
     // Call open table command on tablerunner. 
     // I need a IQueryProvider and IDataReader to pass to the table. 
     return new Table<TEntity>(this.tablerunner, provider,reader, tableName); 
    } 

但現在在我的開放表命令我必須做一個IDataReader和IQueryProvider。如果我將它們傳遞給TableManager的構造函數,這並不違反「僅僅將對象傳遞給內部類型而不真正使用它們」。

我不太確定我是如何做到這一點的。任何人都可以幫助我嗎?

我只是不知道如何分開對象結構和邏輯。

回答

2

一個選項是配置一個TableFactory其中確實知道查詢提供者和讀者,並且只需要知道表名。然後,您可以將工廠傳遞給TableManager。另一方面,TableManager聽起來像它可能需要是工廠本身 - 在這種情況下,它簡單確實需要提供者和讀者,即使它可能不明顯開始,因爲它只是通過它們。

我同意它有點混亂 - 基本上,如果「深入樹中」(和動態創建)需要一條信息,那麼任何創建它的東西都需要這些信息 - 並且創建該創建者需要的信息等等。如果你不小心(有時甚至是你),它肯定會變成一團糟。

根據您的DI框架,您可能能夠在容器中配置一個類似工廠的對象,然後要求在執行時創建一個新實例。這意味着你的代碼會與DI框架相結合 - 這是一個波動和環島的例子。基本上信息必須是某處,並且當你需要時,你總是需要有一些「引用鏈」來獲取它。

遺憾沒能在其上具有更愉快的前景,但即使這些想法不幫你了,至少你知道你並不孤單:)

+0

我想我可能只需要在管理器中使用IQueryProvider和IDataReader。表管理器幾乎只是一個名稱不同的工廠。我觀看了DI與MiškoHevery的谷歌技術演講,並且同意他所說的話,但我永遠無法找到任何現實世界中我所處境況的例子。說「不要僅僅通過對象就好了」他們失望「,但沒有一個例子,這意味着什麼。我正在開發SDK,因此每個部分都需要獨立。 – 2009-07-05 08:27:35

0

您可以加入providerreader作爲參數上OpenTable()

誰在打電話OpenTable()?來電者是否知道providerreader,以便它可以將它們傳遞給該方法?