Создайте функцию «все в одном», используя DS в C # - PullRequest
0 голосов
/ 29 декабря 2008

В моем веб-приложении я использую несколько 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;
}

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

иногда я вижу письмо T , это так? если да, как я могу выполнить такую ​​функцию?

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

Спасибо.

Ответы [ 3 ]

3 голосов
/ 31 декабря 2008

Создайте файл с именем what.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;
    }
    }       
<# } #>
}

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

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

0 голосов
/ 31 декабря 2008

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

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;
}

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

0 голосов
/ 29 декабря 2008

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

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

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

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

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