Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我应该在WCF中分离接口和实现吗?_C#_.net_Wcf - Fatal编程技术网

C# 我应该在WCF中分离接口和实现吗?

C# 我应该在WCF中分离接口和实现吗?,c#,.net,wcf,C#,.net,Wcf,在项目中添加新的WCF服务时,Visual Studio会创建以下两个模板(为了简洁起见,我删除了名称空间和注释): 接下来,我通常会立即将其简化为 [ServiceContract] public class MyService { [OperationContract] void DoWork() { } } 基于这样一种假设,即始终只有一个类实现该接口,并且所有内容都键入两次并没有明显的优势。如果由于某种奇怪和不可预见的原因,将来会有另一个实现(或者我想对

在项目中添加新的WCF服务时,Visual Studio会创建以下两个模板(为了简洁起见,我删除了名称空间和注释):

接下来,我通常会立即将其简化为

[ServiceContract]
public class MyService
{
    [OperationContract]
    void DoWork()
    {
    }
}
基于这样一种假设,即始终只有一个类实现该接口,并且所有内容都键入两次并没有明显的优势。如果由于某种奇怪和不可预见的原因,将来会有另一个实现(或者我想对两个服务使用同一个类),我可以随时在需要时提取接口。毕竟,我与外部世界的契约是WSDL,而不是代码中的接口

然而,当我反对Visual Studio推荐的最佳实践时,我总是持怀疑态度,因此我想问社区:

从一开始就拆分WCF服务的接口和类有什么明显的优势吗?这是我所缺少的吗?

我应该在WCF中分离接口和实现吗

…每样东西都打两次没有明显的好处

撇开客户机模拟服务实现(Adriano在其评论中指出)的能力带来的好处不谈,消费者可以构建一个完全可操作的通道来调用服务,只使用接口类型定义,而不使用其他任何东西

事实上,呼叫服务是消费者的职责。添加服务引用功能最多也很复杂,在您和服务之间添加了另一层,并且在服务定义更改时会导致困难

如果您已经将接口与实现相耦合,那么您的用户就无法干净地使用您的服务,并且被迫使用visual studio mess,即WSDL+代理生成,这远远不是最终契约的先决条件,实际上可以解决的问题

此外,如果您要在纯HTTP(而不是soap)上公开您的操作,那么分离的优势甚至更大。在本例中,您的使用者无法添加服务引用,因此完全依赖于您提供的服务定义类型(或者至少是某种模式,如果您将接口分离出来,那么这种模式将更易于维护)

美国的原则3

服务共享架构和契约,而不是类


这不仅是象征性的,而且是规定性的;您应该将服务的内部实现与其表面公开的内容分离

简而言之,将其作为答案发布,但是:测试。模拟接口非常简单,模拟基类(除非它像接口一样几乎是空的)可能要困难得多。由于VS IDE为我完成了所有的键入工作,所以我通常从一开始就使用一个接口。@AdrianoRepetti:在WCF服务器上,我看不到模拟服务的意义(因为服务是我想要测试的)。在WCF客户端(即服务使用者)上,服务器是否在内部使用接口没有区别,因为WCF客户端使用自动生成的代理类。@Heinzi类。在我看来,这取决于您测试服务的方式。我通常做的是尽可能少地测试实现类的视图(因为……我不想公开它),然后测试接口。对于接口测试,我分两步进行:获取一个实例并测试整体逻辑(例如工作流),然后获取一个服务实例(显然是本地托管的),以测试所有类是否通过服务边界正确序列化。测试实现时,我可能希望模拟一些方法以模拟条件另外,更明显的是,当我测试客户端时,我想测试逻辑(模拟接口)和整个系统(直接使用服务)。还请注意,在测试服务器时,我尝试将其作为客户端进行测试。当然,对于一个简单的服务,您可能不需要这样做,但我发现使用此体系结构比几周后切换到它要容易得多。我同意,我还提到,同一个实现可能会提供同一服务的多个版本(糟糕,我知道,但确实发生了)变化很少。
[ServiceContract]
public class MyService
{
    [OperationContract]
    void DoWork()
    {
    }
}