Dependency Injection for concrete .Net classes
注入/隔离类的首选方法是什么?这些类密封在DLL中,不实现接口?
我们使用NICATION。
假设我们有一个类"server",我们想注入/隔离"server"使用的类tcpserver。
我不想太具体,因为我想知道最好的方法,但我们可以这样说:
1 2 3 4 5 6 7 8 9 10 11 12 13 | public class Server { IServer _server; public Server(IServer server) { _server = server; } public void DoSomething() { _server.DoSomething(); } } |
比如,在测试时,应该给
如果
从具体类中提取接口可能很有诱惑力,但不要这样做。它在接口和具体的类之间创建了一个语义耦合,您很可能最终打破了Liskov替换原则。
相反,根据客户机需要定义接口。这遵循依赖倒置原则;正如APPP,第11章解释的那样:"客户机[…]拥有抽象接口"。角色接口是最好的。
因此,如果您的客户机需要一个
1 2 3 4 | public interface IServer { void DoSomething(); } |
现在可以使用构造函数注入将
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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(); } } |
当涉及到
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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(); } } |
注意,这些方法不必具有相同的名称(甚至完全相同的签名),以便进行修改。