合并WCF操作合同

时间:2019-04-12 07:58:34

标签: wcf

WCF中常见的方法是提供带有多个操作合同的服务。一旦定义了操作合同,最好不要再更改它,因为在很多情况下,操作更改会破坏现有的客户。但是,仅拥有一份通用或通用运营合同(一个合同而不是许多运营合同。实际上,我知道您将不能将所有合同合而为一,而是大多数)。 这里举一个例子。那不是我最终意识到的方式……只是一个简单的例子。

 
public enum Operation
{
    Add,
    Sub,
    Mul,
    Div
 }


[DataContract]
public class Info
{

    [DataMember]
    public Operation Operation { get; set; }

    [DataMember]
    public object Data { get; set; }
}

[ServiceContract]
public interface IService
 {

    [OperationContract]
    Info Do(Info info);
}


public class Service : IService
{
    public Info Do(Info info)
    {
        var result = -1;
        switch (info.Operation)
        {
            case Operation.Add:
                // cast info.Data and calculate result
                break;
            case Operation.Sub:
                // cast info.Data and calculate result
                break; 
        }
        return new Info { Operation = info.Operation, Data = result };
    }
}

通用合同的主要缺点是您必须知道如何将数据传递给服务以及如何解释结果。但这可以通过文档解决。

目前,我正在一个将大型客户端-服务器-应用程序合并为一个解决方案的项目中。添加一项操作,更新服务引用非常麻烦……

合并运营合同不利于什么?我还有什么需要考虑的吗?

1 个答案:

答案 0 :(得分:0)

  

一旦定义了运营合同,最好不要再更改它

     

但是仅拥有一份通用或通用运营合同

[ServiceContract]
public interface IService
 {

    [OperationContract]
    Info Do(Info info);
}

尽管您已尝试使其成为“通用” 或通用,但您实际上没有。这是因为您的服务接口仅接受Info作为参数,没有扩展空间。

Info的成员类型为Operation-枚举,如您正确声明的那样,您不能更改。如果我想一直进行平方根操作会怎样?还是阶乘

请求/响应模式是允许未来请求类型的单方法服务合同的一种方法。本质上,您定义WCF服务合同一次,即使添加新操作,它从不改变 。实际上没有必要。在Request参数中传递的对象本质上是一个标准的信封,其中对实际的特定操作进行了序列化。

例如在这里,我已将您的Request重命名为RequestEnvelope

[ServiceContract]
public interface IService
 {

    [OperationContract]
    ResponseEnvelope Do(RequestEnvelope request);
}

[DataContract]
public class RequestEnvelope 
{
    [DataMember]
    public IRequest Request { get; set; }
}

[DataContract]
public class ResponseEnvelope 
{
    [DataMember]
    public IResponse Response { get; set; }
}

例如,我可能想计算素数,以便将CalculatePrimes的实例序列化为Request的{​​{1}}成员。

RequestEnvelope

当在单个WCF接口上重构具有许多操作的大型整体服务时,这种方法非常有效,从而可以更轻松地管理和减少长期维护。请注意,实际的请求和响应不必是实际的WCF类型而是POCO。