2015-06-15 138 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