结合wcf运营合同

问题描述 投票:0回答:1

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 };
    }
}

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

目前我正在开发一个项目,将一个大型客户端 - 服务器 - 应用程序组合在一个解决方案中。添加一个操作,更新服务引用是一件很麻烦的事......

什么反对合并运营合同?我还有什么需要考虑的吗?

wcf
1个回答
0
投票

一旦定义了操作合同,您最好不要再更改它

但是如何只有一个普通或普遍的运营合同呢?

[ServiceContract]
public interface IService
 {

    [OperationContract]
    Info Do(Info info);
}

虽然你已经试图让它“普遍”或通用,但你真的没有。这是因为您的服务接口只接受Info作为参数,没有扩展空间。

InfoOperation类型的成员 - 一个你无法改变的枚举,正如你所说的那样。如果我想在赛道上进行平方根操作,会发生什么?或者也许是一个因子?

允许未来请求类型的单方法服务合同的一种方法是请求/响应模式。基本上,您只需定义一次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的一个实例序列化为RequestRequestEnvelope成员。

public interface IRequest { }

public interface IResponse { }

[Serializable]
public class CalculatePrimes : IRequest
{
    public int StartAt { get; set; }
    public int CountToCalculate { get; set; }
    public TimeSpan Timeout { get; set; }
}

[Serializable]
public class CalculatePrimesResponse : IResponse
{ 
    public List<int> Primes { get; set; }
}

当将单个WCF接口上的许多操作重构为大型单片服务时,这种方法非常有效,可以实现更易于管理和更少长期维护的操作。请注意实际的请求和响应不必是实际的WCF类型,而是POCO。

© www.soinside.com 2019 - 2024. All rights reserved.