Объединить рабочие контракты wcf - PullRequest
0 голосов
/ 12 апреля 2019

Обычный способ в 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 голосов
/ 14 апреля 2019

Как только контракт на эксплуатацию определен, вам лучше его не менять

Но как насчет одного общего или универсального контракта на эксплуатацию

[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 член RequestEnvelope.

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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...