Создание функции «все в одном» с помощью DS в C#

В своем веб-приложении я использую несколько asmx (веб-служб) от одного и того же поставщика, у них есть один для этого, другой для этого, но для всех требуется заголовок SOAP с проверкой подлинности.

Добавить аутентификацию просто:

public static SoCredentialsHeader AttachCredentialHeader()
{
    SoCredentialsHeader ch = new SoCredentialsHeader();
    ch.AuthenticationType = SoAuthenticationType.CRM5;
    ch.UserId = "myUsername";
    ch.Secret = apUtilities.CalculateCredentialsSecret(
        SoAuthenticationType.CRM5, apUtilities.GetDays(), "myUsername", "myPassword");
    return ch;
}

Проблема в том, что этот SoCredentialsHeader исходит (производный) от ОДНОГО веб-сервиса, и мне нужно добавить тот же код к другим, например:

public static wsContact.SoCredentialsHeader AttachContactCredentialHeader()
{
    wsContact.SoCredentialsHeader ch = new wsContact.SoCredentialsHeader();
    ch.AuthenticationType = wsContact.SoAuthenticationType.CRM5;
    ch.UserId = "myUsername";
    ch.Secret = apUtilities.CalculateCredentialsSecret(
        wsContact.SoAuthenticationType.CRM5, apUtilities.GetDays(), "myUsername", "myPassword");
    return ch;
}

public static wsDiary.SoCredentialsHeader AttachDiaryCredentialHeader()
{
    wsDiary.SoCredentialsHeader ch = new wsDiary.SoCredentialsHeader();
    ch.AuthenticationType = wsDiary.SoAuthenticationType.CRM5;
    ch.UserId = "myUsername";
    ch.Secret = apUtilities.CalculateCredentialsSecret(
        wsDiary.SoAuthenticationType.CRM5, apUtilities.GetDays(), "myUsername", "myPassword");
    return ch;
}

Есть ли способ реализовать шаблон проектирования, чтобы использовать только одну функцию, но которая подходит для всех веб-служб?

иногда вижу букву Т, это к чему? если да, как я могу реализовать такую ​​функцию?

P.S. Я мог бы передать перечисление и использовать переключатель, чтобы проверить имя перечисления и применить правильный заголовок, но каждый раз, когда мне нужно добавить новый WebService, мне нужно добавить перечисление и код, я ищу для этого расширенный метод.

Спасибо.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
276
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Я не знаю, хотите ли вы это рассмотреть, поскольку у него определенно есть свои недостатки, но - поскольку в конечном итоге все они (классы varoius SoCredentialsHeader) являются копиями одного и того же определения класса в разных пространствах имен, поэтому с небольшим количеством при рефакторинге вы можете просто иметь один класс и один метод.

Скопируйте определение класса SoCredentialsHeader в собственный проект, добавьте ссылку на него и удалите определение класса из всех прокси-серверов веб-службы. Добавьте оператор using вверху файла кода прокси, и он не заметит разницы.

По сути, вы сказали ему использовать одно и то же определение класса (ваше) для всех веб-сервисов.

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

эта работа - это то, чего я пытаюсь избежать ... то, что вы говорите, будет таким же, как наличие перечисления, и они применяют правильное пространство имен :)

balexandre 29.12.2008 13:15

Я бы попробовал использовать общий метод, а затем использовать отражение для установки свойств:

public static T AttachDiaryCredentialHeader<T>() where T: class
{
    T ch = new T();
    Type objType = ch.GetType();
    PropertyInfo userId = objType.GetProperty("UserId");
    authType.SetValue(ch, "myUsername", null)
    //And so on for the other properties...
    return ch;
}

ИМХО, это несколько хитроумно, я бы держал их отдельно, если только, как в предыдущем посте, не упоминалось об этом, вы абсолютно уверены, что определения этих сервисов останутся такими же. Одно небольшое изменение в одном из них сломает это.

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

Создайте файл с именем something.tt (трюк - расширение .tt) в любом месте вашего решения VS и вставьте следующий код:

using System;

namespace Whatever
{
    public static class Howdy
    {
<# 
    string[] webServices = new string[] {"wsContact", "wsDiary"};
    foreach (string wsName in webServices)
    {
#>
    public static <#=wsName#>.SoCredentialsHeader AttachContactCredentialHeader()
    {
        <#=wsName#>.SoCredentialsHeader ch = new <#=wsName#>.SoCredentialsHeader();
        ch.AuthenticationType = <#=wsName#>.SoAuthenticationType.CRM5;
        ch.UserId = "myUsername";
        ch.Secret = apUtilities.CalculateCredentialsSecret(<#=wsName#>.SoAuthenticationType.CRM5,
                apUtilities.GetDays(), "myUsername", "myPassword");
        return ch;
    }
    }       
<# } #>
}

Затем посмотрите, как волшебным образом появляется файл something.cs с нужными фрагментами кода. Они называются шаблонами T4 для генерации кода в VS.

Вы захотите превратить их в частичные классы или методы расширения или что-то в этом роде. Приведенный выше код не будет работать «как есть», но вы поняли идею.

Я попробую и поищу больше о шаблонах T4 :)

balexandre 04.01.2009 21:59

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