Как изменить договор на обслуживание 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) и обрабатываю соответственно. На диаграмме ниже показана основная идея - все функции работают через одну функцию, которая принимает и отправляет один и тот же простой класс в качестве параметров. Таким образом, мой интерфейс никогда не нужно менять.