Таким образом, в настоящее время в моем решении добавлено 2 WSDL в качестве ссылок на услуги. Они выглядят так в моем файле app.config (я удалил поле «bindings», потому что это неинтересно):
<system.serviceModel>
<client>
<endpoint address="http://localhost:8080/query-service/jse" binding="basicHttpBinding" bindingConfiguration="QueryBinding" contract="QueryService.Query" name="QueryPort" />
<endpoint address="http://localhost:8080/dataimport-service/jse" binding="basicHttpBinding" bindingConfiguration="DataImportBinding" contract="DataService.DataImport" name="DataImportPort" />
</client>
</system.serviceModel>
Когда я использую WSDL, это выглядит примерно так:
using (DataService.DataClient dClient = new DataService.DataClient())
{
DataService.importTask impt = new DataService.importTask();
impt.String_1 = "someData";
DataService.importResponse imptr = dClient.importTask(impt);
}
В выражении "using" при создании экземпляра объекта DataClient у меня есть 5 доступных конструкторов. В этом сценарии я использую конструктор по умолчанию:
new DataService.DataClient()
, который использует встроенную строку адреса конечной точки, которая, как я полагаю, извлечена из app.config. Но я хочу, чтобы у пользователя приложения была возможность изменить это значение.
1) Какой самый лучший / простой способ программного получения этой строки?
2) Тогда, как только я разрешу пользователю редактировать и проверять значение, где мне его хранить?
Я бы предпочел, чтобы оно хранилось в каком-либо месте (например, app.config или эквивалентном), чтобы не было необходимости проверять, существует ли значение или нет, и следует ли мне использовать альтернативный конструктор. (Хочешь держать мой код в узде, понимаешь?)
Есть идеи? Предложения?
EDIT
Может быть, мне стоит спросить и об этих альтернативных конструкторах.
Например, один из них выглядит так:
new DataService.DataClient(string endPointConfigurationName,
string remoteAddress)
Какие значения могут быть переданы для "endPointConfigurationName" и "remoteAddress"?
EDIT2
Отвечая на мои собственные вопросы, «endPointConfigurationName» выглядит так же, как «name» в XML-файле app.config, а «remoteAddress» форматируется так же, как «адрес конечной точки» в XML-файле app.config.
Также! Ответ на мой первый вопрос о получении EndPointAddresses следующий:
ClientSection clSection =
ConfigurationManager.GetSection("system.serviceModel/client") as ClientSection;
ChannelEndpointElementCollection endpointCollection =
clSection.ElementInformation.Properties[string.Empty].Value as ChannelEndpointElementCollection;
Dictionary<string, string> nameAddressDictionary =
new Dictionary<string, string>();
foreach (ChannelEndpointElement endpointElement in endpointCollection)
{
nameAddressDictionary.Add(endpointElement.Name,
endpointElement.Address.ToString());
}
EDIT3
Хорошо, я думаю, что я выяснил 2-ую половину (и, таким образом, полное решение) моей проблемы. Я нашел это на другом сайте, и я изменил его, чтобы удовлетворить мои потребности:
Configuration configuration;
ServiceModelSectionGroup serviceModelSectionGroup;
ClientSection clientSection;
configuration =
ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
serviceModelSectionGroup =
ServiceModelSectionGroup.GetSectionGroup(configuration);
clientSection = serviceModelSectionGroup.Client;
foreach (ChannelEndpointElement endPt in clientSection.Endpoints)
{
MessageBox.Show(endPt.Name + " = " + endPt.Address);
}
configuration.Save();
С помощью этого кода у нас есть доступ к clientSection.Endpoints и мы можем получить доступ и изменить все свойства элемента, такие как «Адрес». И затем, когда мы закончим их изменение, мы можем выполнить конфигурацию. Save () и все значения записываются в пользовательский файл.
Теперь вот подвох. В режиме отладки «configuration.save ()» не сохраняет ваши значения от исполнения к выполнению, но при нормальном запуске приложения (вне режима отладки) значения сохраняются. (Это хорошо.) Так что это единственное предостережение.
EDIT4
Есть еще одна оговорка. Изменения, внесенные в WSDL, не вступают в силу во время выполнения. Приложение необходимо перезапустить, чтобы перечитать значения файла конфигурации пользователя в память (по-видимому.)
Единственное, что меня может заинтересовать, - это найти способ (после изменения значений) вернуть значения по умолчанию. Конечно, вы можете удалить пользовательский файл, но при этом удаляются все пользовательские настройки.
Есть идеи?
EDIT5
Я думаю, что инъекция зависимости может быть идеальной здесь, но нужно исследовать это подробнее ...
РЕДАКТИРОВАТЬ 6
У меня нет прав на комментарии, но вам нужно запустить
ConfigurationManager.RefreshSection("client");
обновить кэш, чтобы изменения произошли немедленно.