Как изменить договор на обслуживание WCF, который не влияет на клиента?

Я новичок, но прочитав какую-то статью о 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, который не создаст никаких проблем, если мы расширим функциональность или внесем какие-либо изменения, но клиентская часть не столкнется с какой-либо проблемой. Спасибо

1 ответ

Решение

У меня была та же проблема, в основном постоянный набор изменений в методах, которые нарушали бы интерфейсы на клиентах.

Это то, что я сделал: все мои 30+ функций (и список растет и растет) принимали строки, целые и байты () в качестве типов данных как входные и выходные параметры, я создал единую главную конечную точку и функцию, которая получает, как входной параметр и отправляет обратно в качестве вывода, один простой класс. Этот класс, называемый HostInterface, содержит всего два параметра: строку (которую я использую для инкапсуляции всех моих строк и целых) и массив byte() (в который я вставляю все свои двоичные файлы)

Таким образом, независимо от того, вызывает ли клиент что-то простое, например, Ping() с одним строковым параметром, или что-то сложное, например, ResumeDownload() с 5 строками, 2 int и байтовым массивом, все эти параметры инкапсулируются в моем классе HostInterface, в строках. и вставляет в один параметр String (как XML), а байты - в поле байтов.

Когда запрос получен на стороне хоста здесь:

  Function HostConnect(byval objInbound as HostInterface) as HostInterface

Я распаковываю строковый параметр в objInbound, превращая XML в объект, и я распаковываю байты и добавляю их в байтовую часть того же объекта. Затем я проверяю имя метода (ping или ResumeDownload) и обрабатываю соответственно. На диаграмме ниже показана основная идея - все функции работают через одну функцию, которая принимает и отправляет один и тот же простой класс в качестве параметров. Таким образом, мой интерфейс никогда не нужно менять.

Другие вопросы по тегам