Ссылка на библиотеку классов без ссылки на ссылки на службы библиотеки

Я работаю со сторонней системой, которая доступна только через веб-сайты и ссылки на сервисы. При создании службы Windows, которая обрабатывает автоматизированную обработку, я обнаружил, что если ссылки на веб-службы используются решением, они также должны быть настроены в любом решении, которое ссылается на первое.

Есть ли способ предотвратить это? Я хотел бы создать библиотеку классов, которая будет содержать все фактические вызовы API и использовать ее как пакет NuGet без необходимости также добавлять ссылки на каждый проект в будущем.

EDIT: Вот пример того, как я сейчас вызываю API:

internal class ApiAccess
{
    private readonly Account_SSPSoapClient _apiAccount;

    public ApiAccess()
    {
        _apiAccount = new Account_SSPSoapClient();
    }

    public string GetAccountId(string accountName)
    {
        return _apiAccount.GetID(accountName);
    }
}

person Logarr    schedule 13.03.2013    source источник


Ответы (1)


Это проблема, но это не та проблема, которой кажется.

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

Самый простой случай:

var request = new MyServiceRequest { /* set properties here */ };
var client  = MyServiceReferenceClient(new BasicHttpBinding(), new EndpointAddress(@"https://my.service.com/path/to/service"));
var channel = client.ChannelFactory.CreateChannel();
var result  = channel.MyService(request);

Вы захотите установить некоторые параметры в BasicHttpBinding, чтобы они соответствовали тому, что находится в файле app.config, и URL-адрес также выходит оттуда.

См. этот ответ, почему он не работает по умолчанию.


Изменить: для вашего кода вы просто замените new Account_SSPSoapClient(); чем-то вроде:

new Account_SSPSoapClient(new BasicHttpBinding(), new EndpointAddress(@"https://my.service.com/path/to/service"));

Все остальное должно быть таким же, но он будет использовать эти значения вместо значений app.config (что он и делает без параметров).

Найдите в файле app.config что-то вроде:

    <bindings>
        <basicHttpBinding>
            <binding name="LabelRecoveryBinding" closeTimeout="00:01:00"
                openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
                useDefaultWebProxy="true">
                <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                    maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                <security mode="None">
                    <transport clientCredentialType="None" proxyCredentialType="None"
                        realm="" />
                    <message clientCredentialType="UserName" algorithmSuite="Default" />
                </security>
            </binding>
        </basicHttpBinding>

Все в этом соответствует свойству, которое вы можете установить для объекта BasicHttpBinding, созданного выше — большая часть из них является значениями по умолчанию, но вы можете захотеть установить все вручную на всякий случай.

Так же ищите

<client>
        <endpoint address="http://153.2.133.60:48010/xoltws_ship/LBRecovery"
            binding="basicHttpBinding" bindingConfiguration="LabelRecoveryBinding"
            contract="UPSLabelRecoveryService.LabelRecoveryPortType" name="LabelRecoveryPort" />
</client>

Это говорит вам, какой URL предоставить для new EndpointAddress.

person Bobson    schedule 13.03.2013
comment
Не могли бы вы немного подробнее рассказать об этом? Этот фрагмент кода входит в библиотеку классов или в проект, который на него ссылается? - person Logarr; 13.03.2013
comment
@Logarr - Отредактировано - Это помогает? Он идет в библиотеку классов, где вы (предположительно) уже делаете вызов. - person Bobson; 13.03.2013
comment
Не совсем... Я отредактировал вопрос, чтобы показать пример того, как я сейчас вызываю API. Я не вижу, как применить ваш метод в этом случае. - person Logarr; 13.03.2013
comment
@Logarr - А, это помогает прояснить ситуацию. Отредактировано. - person Bobson; 13.03.2013
comment
Это имеет больше смысла. Я не то чтобы полностью заменяю app.config, а программно переопределяю его. Спасибо! - person Logarr; 13.03.2013
comment
@Logarr - Точно! Извлекая то, что вам нужно, из конфигурации в код, его можно компилировать и распространять без необходимости изменять какие-либо другие файлы app.config. Рад, что это помогло! - person Bobson; 13.03.2013