2014-03-04 50 views
5

我试图做整个应用层依赖注入和正在运行到一个场景我相信其他人都看到了。我们使用了一些第三方Web服务,客户端是使用基类自动生成的。客户端没有接口,数据类型在同一个文件/项目中。DI与自动生成的Web服务客户端

明显的问题是,如果我想要做单元测试我需要模拟服务。我需要提取一个接口并将数据类型移动到一个“合同”项目中,这个项目可供真实/模拟客户端使用。但是,下次客户端自动生成时需要重做该工作。在运行时创建一个代理没有什么帮助,因为那样我们就不得不从WSDL手动创建接口和数据类型。有没有更好的方法来处理这个问题?

+4

在这种情况下,通过Microsoft Fakes垫片是否会对您有用? http://msdn.microsoft.com/en-us/library/hh549175.aspx –

+0

@BrendanGreen - 今天学到的新东西+1。这可能可行,但由于我控制了客户端代码,我希望尽可能避免使用此路由。绝对是未来的一个好工具。 –

回答

5

提取从实现的接口是不会帮助你多少反正这将是一个糟糕的抽象。

接口应由使用接口的客户端定义和拥有。如Agile Principles, Patterns, and Practices解释,“客户端拥有抽象接口”(第11章)。因此,任何试图定义像自动生成的Web服务客户端提取接口这样以数据为中心的接口的尝试迟早都会导致问题,因为它违反了各种SOLID原则,例如依赖反转原理或接口分离原则。

相反,你客户端代码应该定义他们需要的接口。然后,您可以始终使用实施与自动生成的Web服务客户端的接口。如果你使用微软的工具(Visual Studio中,Wsdl.exe用等)相关的自动生成的类应该已经是一个部分类,这意味着你应该能够添加行为,它不接触自动生成一部分。

+0

试图理解...为什么要提取一个接口违反DI原则?其余的代码只是引用接口,实例可以由IoC容器提供。接口隔离我明白了,因为提取接口可能会导致不需要的成员,但如果可能使用服务提供的大部分/全部内容,它可以用作起点并清理它。 –

+0

关于拥有接口和部分类的客户端,你是否说我应该在部分类中添加业务逻辑,以便从接口映射到服务实际提供的内容?这是一个有趣的概念,以便在服务发生变化时,依赖于接口的代码不一定需要更改,但如果它足够复杂,我想测试该业务逻辑,并且我马上回到了开始的位置。 –

+0

DIP说:“抽象不应该取决于细节,细节应该取决于抽象。”如果接口在与服务相同的包中定义,则客户端依赖于服务包(实现细节)。这就是DIP指出客户应该拥有他们所需接口的原因。是的,您可能需要测试转换逻辑,但这不是业务逻辑,这是实现细节的一部分。业务逻辑应该是独立封装(S):http://blog.ploeh.dk/2013/12/03/layers-onions-ports-adapters-its-all-the-same –