需要最佳指导以后更改WCF服务合同

时间:2014-01-30 07:21:53

标签: c# wcf servicecontract

我是新手,但是在阅读有关wcf的一些文章后我才知道,如果我更改ServcieContrcat,那么我不仅要更改服务端,而且还要更改客户端,这真的很难管理。

Example 1:

开发人员必须为订单处理创建WCF服务,具有以下功能:GetOrderById, GetOrdersByStatus, SaveOrder

ServiceContract可能如下所示

[ServiceContract]
public interface IOrderService
{
    [OperationContract]
    Order GetOrderById(int orderId);

    [OperationContract]
    List<Order> GetOrdersByStatus(OrderStatus orderStatus);

    [OperationContract]
    void SaveOrder(Order order)
} 
例如,几个月后,项目经理说:好的,我们的客户需要其他功能:DeleteOrderById, GetOrdersByCustomerId而且不再需要GetOrdersByStatus,我们需要GetOrdersByStatusAndCustomerId

开发人员必须更新ServiceContrcat并更新客户端。如您所见,ServiceContrcat中的任何更改都非常困难

所以我正在寻找如何开发wcf服务的最佳指导,如果我们扩展功能或任何类型的更改,但客户端不会遇到任何问题,这将不会产生任何问题。感谢

一个人之前回答过同样的情况

这就是我所做的:我所有的30多个函数(以及列表增长和增长)都将字符串,整数和字节()作为数据类型作为输入和输出参数,我创建了一个主单端点和函数接收作为输入参数,并作为输出发回一个简单类。这个名为HostInterface的类只包含两个参数,一个字符串(用于封装我的所有字符串和整数)和一个byte()数组(我将所有二进制文件填入其中)

因此,无论客户端是仅使用一个字符串参数调用类似Ping()的简单函数,还是像5个字符串,2个整数和一个字节数组那样复杂的ResumeDownload(),所有这些参数都封装在我的HostInterface类中,将字符串和整数转换为一个String参数(如XML),将字节转换为字节字段。

我很欣赏他的答案但真的不明白如何实现它。所以如果有人去了这个网址How to change WCF service contract which does not effect client?

然后知道他说了什么。

我正在寻找小型完整的wcf服务代码,它帮助我可视化如何设计服务合同,如果我们稍后扩展服务合同的功能,那么将使用我的服务的客户将不会遇到任何问题。

并告诉我其他可能的指导方针来解决这种情况。感谢

2 个答案:

答案 0 :(得分:2)

我认为创建通用端点的建议是个坏主意。通过创建一个接受任何类型输入的方法,您已经失去了C#中的WCF带给您的所有强类型优势。您仍然需要处理与旧客户打交道的艰苦工作,但现在您必须通过检查进入的数据并启发式决定它假定的“版本”来在应用程序代码中执行此操作。在我看来,它类似于创建一个SQL数据库表,其中有几列名为iddata1data2data3data4等。 ,然后在那一个表中存储各种不相关的数据。

如果合同发生变化,您需要进行向后兼容,那么您可以将其添加到合同中。添加新方法是向后兼容的,因为它不会影响现有方法的可用性。

如果您需要进行向后不兼容的更改(例如删除方法或更改现有方法的参数),最简单的答案可能是创建一个位于新地址的新合同。如果在http://example.com/v1/MyService达到合同的第1版,则会在http://example.com/v2/MyService达到第2版。

为避免在合同没有太大变化的类之间复制大量代码,实现合同的类可能会相互继承。一种方法可以是:

namespace V1
{
    [ServiceContract]
    public interface IService { ... }
    public class MyService : IService { ... }
}

namespace V2
{
    [ServiceContract]
    public interface INewService { ... }
    public class MyNewService : V1.MyService, INewService { ... }
}

或者您可以使用合成:

public class MyNewService : INewService
{
    private readonly V1.MyService v1service = new V1.MyService();

    public int SomeMethod()
    {
        return this.v1service.SomeMethod();
    }
}

这样,MyNewService实现了MyService的所有功能,但只有INewService公开的方法才能通过WCF获得。通过v2 URL访问您的服务的任何人都将获得新功能。使用旧服务的客户端将继续使用v1 URL,直到他们准备好升级。

答案 1 :(得分:1)

如果我正确理解你的问题,那么ChannelFactory类可能会拯救你(部分至少)。链接here将帮助您入门。

此外,您可能希望使用IExtensibleDataObject进行前向兼容。请查看链接here以便更好地理解。

希望这有帮助。