Рефакторинг доверенного фасада WCF

Я пытаюсь реорганизовать «доверенный фасад», который в настоящее время переносит более 50 вызовов службы на серверную часть. Все звонки имеют разные подписи, но все остальное повторяется. Проблема с существующими вызовами заключалась в том, что не было предпринято никаких попыток управлять соединениями, в результате чего эфемерные порты оставались в состоянии «BOUND».

ОРИГИНАЛЬНЫЙ КОД:

public class ReportWeb : IReportWeb
{
    ReportService.ReportClient client = new ReportClient();
    ...
    
    public string[] GetAccounts() => client.GetAccounts();
}

НОВЫЙ КОД:

private ChannelFactory<IReportService> _factory = null;
private IReportService _proxy = null;

private void OpenProxy()
{
    _factory = new ChannelFactory<IReportService>("NetTcpBinding_IReportService");
    _proxy = _factory.CreateChannel();
}

private void CloseProxy()
{
    ((IClientChannel)_proxy).Close();
    _factory.Close();
}

Один из 50+ подобных методов:

public string[] GetAccounts() // Different - name, params, and return type
{
    string[] accounts = null; // Different

    try
    {
        OpenProxy();
        accounts = _proxy.GetAccounts();  // Different
        CloseProxy();
    }
    catch (Exception exception)
    {
        bool faulted = _factory.State == CommunicationState.Faulted;
        _factory.Abort();

        if (faulted)
        {
            throw new ApplicationException(exception.Message);
        }
        else
        {
            throw;
        }
    }
    return accounts;
}

Еще один аналогичный метод:

//Another method
public ContractsInfo[] GetContracts(int contractId) // Different - 
    // name, params, and return type
{
    ContractsInfo[] contracts = null; // Different

    try
    {
        OpenProxy();
        contracts = _proxy.GetContracts(contractId); // Different
        CloseProxy();
    }
    catch (Exception exception)
    {
        bool faulted = _factory.State == CommunicationState.Faulted;
        _factory.Abort();
        if (faulted)
        {
            throw new ApplicationException(exception.Message);
        }
        else
        {
            throw;
        }
    }
    return contracts;
}

Код вызова из проекта Web Forms:

public string[] GetAccounts()
{
    ReportClient client = NewReportClient();
    string[] results = null;

    try
    {
        results = client.GetAccounts();
        client.Close();
    }
    catch (Exception ex)
    {
        client.Abort();
        throw ex;
    }
    return results;
}

Существует более пятидесяти других методов, таких как GetData(), с разными сигнатурами. Все они будут идентичны, за исключением вызова службы в каждом, который будет различаться параметрами и типом возвращаемого значения. Мне нужен более абстрактный или общий способ кодирования и, таким образом, придерживаться принципа DRY. Func<T, TResult> Delegate здесь уместно? В любом случае, может ли кто-нибудь предложить лучший подход здесь с некоторым кодом-заглушкой для иллюстрации?

Сухой принцип, о котором вы сказали, означает не повторяться, то есть не повторять одно и то же. У вас есть много методов, которые лишь немного отличаются друг от друга, поэтому вы хотите разработать общий способ уменьшить количество избыточности в вашем коде.

Jiayao 22.11.2022 08:19
Как настроить Tailwind CSS с React.js и Next.js?
Как настроить Tailwind CSS с React.js и Next.js?
Tailwind CSS - единственный фреймворк, который, как я убедился, масштабируется в больших командах. Он легко настраивается, адаптируется к любому...
LeetCode запись решения 2536. Увеличение подматриц на единицу
LeetCode запись решения 2536. Увеличение подматриц на единицу
Увеличение подматриц на единицу - LeetCode
Переключение светлых/темных тем
Переключение светлых/темных тем
В Microsoft Training - Guided Project - Build a simple website with web pages, CSS files and JavaScript files, мы объясняем, как CSS можно...
Отношения &quot;многие ко многим&quot; в Laravel с методами присоединения и отсоединения
Отношения &quot;многие ко многим&quot; в Laravel с методами присоединения и отсоединения
Отношения "многие ко многим" в Laravel могут быть немного сложными, но с помощью Eloquent ORM и его моделей мы можем сделать это с легкостью. В этой...
В PHP
В PHP
В большой кодовой базе с множеством различных компонентов классы, функции и константы могут иметь одинаковые имена. Это может привести к путанице и...
Карта дорог Беладжар PHP Laravel
Карта дорог Беладжар PHP Laravel
Laravel - это PHP-фреймворк, разработанный для облегчения разработки веб-приложений. Laravel предоставляет различные функции, упрощающие разработку...
1
1
80
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я полагаю, что это тот случай, когда можно применить общий метод с. это можно прочитать о дженериках здесь

Позвольте мне показать пример кода:

public class Foo
{ 
    public T GetDate<T, UArg>(UArg arg) where T : new()
    {
        return new T();
    }
}

Имеет смысл, за исключением того, что это тип фасада, и все его методы имеют разные имена, параметры и типы возвращаемых значений. Если бы я попытался пойти по этому пути, я бы изменил API, а затем также должен был бы изменить более 50 вызовов API в клиенте? Я обновил код, чтобы показать, что будет отличаться. Мысль, что использование Func<...> может сработать...

IrishChieftain 22.11.2022 14:11

@IrishChieftain, не могли бы вы показать больше примеров различных методов, таких как GetData()?

StepUp 22.11.2022 15:42

Сделанный. Некоторые методы имеют три или четыре разных параметра и совершенно разные типы возвращаемых значений. Я попытался извлечь исключение из метода, но столкнулся с загадкой «выбросить или выбросить исключение».

IrishChieftain 22.11.2022 16:02

@IrishChieftain Правильно ли я понял, что все эти 50 методов находятся в классе ReportWeb? Если да, можете ли вы опубликовать код, который вызывает эти методы?

StepUp 22.11.2022 16:07

Добавлен код вызова клиента.

IrishChieftain 22.11.2022 16:34

@IrishChieftain спасибо за ваши обновления. Я полагаю, как вы сказали, можно использовать Func. Я думал, что здесь можно использовать шаблон Template, но это не тот случай, так как все 50 методов размещены в одном классе, и это требует огромного рефакторинга кода.

StepUp 22.11.2022 16:36

Есть ли какой-то процесс по этому вопросу.

Jiayao 01.12.2022 11:05

@Jiayao, универсального решения не существует, так как многие методы имеют разные сигнатуры. Я отмечаю SetUp как правильный ответ, потому что он все еще может упростить проблему, имея интерфейс с набором функций, которые соответствуют тому, что необходимо.

IrishChieftain 16.12.2022 15:30

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