混凝土.Net类的依赖注入

Guy*_*vin 1 .net c# dependency-injection ninject

注入/隔离密封在dll中并且不实现接口的类的首选方法是什么?

我们使用Ninject.

假设我们有一个类"Server",我们想要注入/隔离"Server"使用的类TcpServer.

不想太具体,因为我想知道最好的方法,但让我们这样说:

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

    public void DoSomething()
    {
        _server.DoSomething();     
    }
}
Run Code Online (Sandbox Code Playgroud)

_server 在测试的情况下,应该注入TcpClient或mock

Mar*_*ann 8

如果TcpServer是密封的,未实现的接口,但你还是想从它的具体实现解耦客户端,你必须定义一个接口,客户端可以聊得来,以及一个适配器TcpServer到新的界面.

从具体类中提取接口可能很诱人,但不要这样做.它在界面和具体类之间创建了一个语义耦合,你最希望最终打破Liskov替换原则.

相反,根据客户端需要定义接口.这来自依赖倒置原则 ; 作为APPP,第11章解释说:" 客户[...]拥有抽象接口 ".一个角色界面是最好的.

因此,如果您的客户端需要一个DoSomething方法,那么您只需添加到该接口:

public interface IServer
{
    void DoSomething();
}
Run Code Online (Sandbox Code Playgroud)

您现在可以IServer使用Constructor Injection注入您的客户端:

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();     
    }
}
Run Code Online (Sandbox Code Playgroud)

说到这一点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();
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,这些方法不必具有相同的名称(甚至完全相同的签名)才能进行调整.