2015-06-15 113 views
1

注入/隔離封裝在dll中但不實現接口的類的首選方法是什麼?具體.Net類的依賴注入

我們使用Ninject。

假設我們有一個類「服務器」,我們要注入/隔離類TCPSERVER其中「服務器」使用。

不想太具體,因爲我想知道的最佳途徑,但讓我們說這樣的事情:

public class Server 
{ 
    IServer _server; 
    public Server(IServer server) 
    { 
     _server = server; 
    } 

    public void DoSomething() 
    { 
     _server.DoSomething();  
    } 
} 

_server應與注射,讓我們說,TcpClient的或模擬的情況下測試

+1

您能否提供一些示例代碼並解釋您試圖實現的目標? – dotnetom

+3

您可以將[具體依賴關係](http://blog.ploeh.dk/2012/08/31/ConcreteDependencies)注入客戶端,但是否會幫助您取決於您​​首先執行此操作的動機。你爲什麼想這樣做? –

+0

用示例編輯帖子。這樣做的原因是爲了測試,我不希望內部類影響。另外,我想用其他方法替換內部類的方法 –

回答

8

如果TcpServer是密封的,未實現的接口,但你還是想從它的具體實現解耦客戶端,你必須定義一個接口,客戶端可以聊得來,還有一個AdapterTcpServer新的界面。

從具體類中提取接口可能很誘人,但不要這樣做。它創建了界面和具體類之間的語義耦合,最終你最終打破了Liskov Substitution Principle

取而代之的是,在的什麼客戶需要方面的接口。這來自Dependency Inversion Principle;作爲APPP,第11章解釋:「客戶端擁有抽象接口」。 A Role Interface是最好的。

因此,如果您的客戶端需要一個DoSomething方法,這就是你添加到接口:

public interface IServer 
{ 
    void DoSomething(); 
} 

現在,您可以注入IServer到您的客戶端,使用構造器注入

public class Client 
{ 
    private readonly IServer server; 

    public Client(IServer server) 
    { 
     if (server == null) 
      throw new ArgumentNullException("server"); 

     this.server = server; 
    } 

    public void DoFoo() 
    { 
     this.server.DoSomething();  
    } 
} 

當涉及到TcpServer時,您可以在其上創建一個適配器:

public class TcpServerAdapter : IServer 
{ 
    private readonly TcpServer imp; 

    public TcpServerAdapter(TcpServer imp) 
    { 
     if (imp == null) 
      throw new ArgumentNullException("imp"); 

     this.imp = imp; 
    } 

    public void DoSomething() 
    { 
     this.imp.DoWhatever(); 
    } 
} 

請注意,方法不必具有相同的名稱(甚至完全相同的簽名)才能進行修改。

+0

馬克,你知道嗎,你可以簡單地參考DIP的維基百科文章,而不是鏈接到APPP,因爲它指出:「這些摘要屬於上層/策略層。保存購買該書的OP :-)。但當然,每個開發人員都必須閱讀APPP,所以指出這不是犯罪:D – Steven

+0

@Steven我不知道。謝謝你指出:) –

+0

這是因爲這是對文章的一個相當新的變化。該更改是在[2015年1月]中進行的(https://en.wikipedia.org/w/index.php?title=Dependency_inversion_principle&diff=666499143&oldid=643053252)。但這是很大的改變;我現在經常引用這部分內容。從參考APPP節省我。 – Steven