Поддержка конфигурации и метаданных

В этом разделе описывается, как включить поддержку конфигурации и метаданных для привязок и элементов привязки.

Общие сведения о конфигурации и метаданных

В этом разделе рассматриваются следующие задачи, которые являются необязательными элементами 1, 2 и 4 в списке задач "Разработка каналов ".

  • Включение поддержки файла конфигурации для элемента привязки.

  • Включение поддержки файла конфигурации для привязки.

  • Экспорт утверждений WSDL и политик для элемента привязки.

  • Определение утверждений WSDL и утверждений политик для вставки и настройки параметра привязки или элемента привязки.

Сведения о создании определяемых пользователем привязок и элементов привязки можно найти в "Создание привязок User-Defined" и "Создание элемента привязки" соответственно.

Добавление поддержки конфигурации

Чтобы включить поддержку файлов конфигурации для канала, необходимо реализовать два раздела конфигурации: System.ServiceModel.Configuration.BindingElementExtensionElement, что обеспечивает поддержку конфигурации элементов привязки, и System.ServiceModel.Configuration.StandardBindingElement и System.ServiceModel.Configuration.StandardBindingCollectionElement<TStandardBinding,TBindingConfiguration>, которые обеспечивают поддержку конфигурации привязок.

Для этого проще использовать пример средства ConfigurationCodeGenerator для создания кода конфигурации для привязок и элементов привязки.

Расширение элемента BindingElementExtensionElement

Следующий пример кода взят из образца Transport: UDP. Это UdpTransportElementBindingElementExtensionElement, который предоставляет доступ к UdpTransportBindingElement системе конфигурации. С помощью нескольких основных переопределений пример определяет имя раздела конфигурации, тип элемента привязки и как создать элемент привязки. Затем пользователи могут зарегистрировать раздел расширения в файле конфигурации следующим образом.

<configuration>
  <system.serviceModel>
    <extensions>
      <bindingElementExtensions>
      <add name="udpTransport" type="Microsoft.ServiceModel.Samples.UdpTransportElement, UdpTransport" />
      </bindingElementExtensions>
    </extensions>
  </system.serviceModel>
</configuration>

Расширение можно использовать в пользовательских привязках для применения UDP в качестве транспорта.

<configuration>
  <system.serviceModel>
    <bindings>
      <customBinding>
       <binding configurationName="UdpCustomBinding">
         <udpTransport/>
       </binding>
      </customBinding>
    </bindings>
  </system.serviceModel>
</configuration>

Добавление конфигурации для привязки

Этот раздел SampleProfileUdpBindingCollectionElement является StandardBindingCollectionElement<TStandardBinding,TBindingConfiguration>, который открывает SampleProfileUdpBinding для системы конфигурации. Основная реализация делегируется SampleProfileUdpBindingConfigurationElement, который происходит от StandardBindingElement. У SampleProfileUdpBindingConfigurationElement есть свойства, которые соответствуют свойствам на SampleProfileUdpBinding, а также функции для отображения из привязки ConfigurationElement. Наконец, метод OnApplyConfiguration переопределяется в SampleProfileUdpBinding, как показано в следующем коде примера.

protected override void OnApplyConfiguration(string configurationName)
{
            if (binding == null)
                throw new ArgumentNullException("binding");

            if (binding.GetType() != typeof(SampleProfileUdpBinding))
            {
                var expectedType = typeof(SampleProfileUdpBinding).AssemblyQualifiedName;
                var typePassedIn = binding.GetType().AssemblyQualifiedName;
                throw new ArgumentException($"Invalid type for binding. Expected type: {expectedType}. Type passed in: {typePassedIn}.");
            }
            SampleProfileUdpBinding udpBinding = (SampleProfileUdpBinding)binding;

            udpBinding.OrderedSession = this.OrderedSession;
            udpBinding.ReliableSessionEnabled = this.ReliableSessionEnabled;
            udpBinding.SessionInactivityTimeout = this.SessionInactivityTimeout;
            if (this.ClientBaseAddress != null)
                   udpBinding.ClientBaseAddress = ClientBaseAddress;
}

Чтобы зарегистрировать этот обработчик в системе конфигурации, добавьте следующий раздел в соответствующий файл конфигурации.

<configuration>
  <configSections>
     <sectionGroup name="system.serviceModel">
         <sectionGroup name="bindings">
                 <section name="sampleProfileUdpBinding" type="Microsoft.ServiceModel.Samples.SampleProfileUdpBindingCollectionElement, UdpTransport" />
         </sectionGroup>
     </sectionGroup>
  </configSections>
</configuration>

Затем можно обратиться к <разделу конфигурации system.serviceModel>.

<configuration>
  <system.serviceModel>
    <client>
      <endpoint configurationName="calculator"
                address="soap.udp://localhost:8001/"
                bindingConfiguration="CalculatorServer"
                binding="sampleProfileUdpBinding"
                contract= "Microsoft.ServiceModel.Samples.ICalculatorContract">
      </endpoint>
    </client>
  </system.serviceModel>
</configuration>

Добавление поддержки метаданных для элемента связывания

Чтобы интегрировать канал в систему метаданных, он должен поддерживать как импорт, так и экспорт политики. Это позволяет таким средствам, как служебная программа метаданных ServiceModel (Svcutil.exe) создавать клиенты элемента привязки.

Добавление поддержки WSDL

Элемент транспортной привязки в привязке отвечает за экспорт и импорт информации об адресации в метаданных. При использовании привязки SOAP элемент привязки транспорта также должен экспортировать правильный URI транспорта в метаданных. Следующий пример кода взят из образца Transport: UDP.

Экспорт WSDL

UdpTransportBindingElement реализует интерфейс System.ServiceModel.Description.IWsdlExportExtension, чтобы экспортировать сведения об адресации. Метод IWsdlExportExtension.ExportEndpoint добавляет правильные сведения об адресации в порт WSDL.

if (context.WsdlPort != null)
{
    AddAddressToWsdlPort(context.WsdlPort, context.Endpoint.Address, encodingBindingElement.MessageVersion.Addressing);
}

Реализация UdpTransportBindingElementExportEndpoint метода также экспортирует URI транспорта, если конечная точка использует привязку SOAP:

WsdlNS.SoapBinding soapBinding = GetSoapBinding(context, exporter);
if (soapBinding != null)
{
    soapBinding.Transport = UdpPolicyStrings.UdpNamespace;
}

Импорт WSDL

Чтобы расширить систему импорта WSDL для обработки импорта адресов, добавьте следующую конфигурацию в файл конфигурации для Svcutil.exe, как показано в файле Svcutil.exe.config:

<configuration>
  <system.serviceModel>
    <client>
      <metadata>
        <wsdlImporters>
          <extension type=" Microsoft.ServiceModel.Samples.UdpBindingElementImporter, UdpTransport" />
        </wsdlImporters>
      </metadata>
    </client>
  </system.serviceModel>
</configuration>

При запуске Svcutil.exeсуществует два варианта получения Svcutil.exe для загрузки расширений импорта WSDL:

  1. Направьте Svcutil.exe на файл конфигурации, используя команду /SvcutilConfig:<file>.

  2. Добавьте раздел конфигурации в Svcutil.exe.config в том же каталоге, что и Svcutil.exe.

Тип UdpBindingElementImporter реализует System.ServiceModel.Description.IWsdlImportExtension интерфейс. Метод ImportEndpoint импортирует адрес из порта WSDL:

BindingElementCollection bindingElements = context.Endpoint.Binding.CreateBindingElements();
TransportBindingElement transportBindingElement = bindingElements.Find<TransportBindingElement>();
if (transportBindingElement is UdpTransportBindingElement)
{
    ImportAddress(context);
}

Добавление поддержки политик

Элемент пользовательской привязки может выводить утверждения политики в привязке WSDL для служебной конечной точки, чтобы выразить возможности этого элемента привязки. Следующий пример кода взят из образца Transport: UDP.

Экспорт политики

Тип UdpTransportBindingElement реализует System.ServiceModel.Description.IPolicyExportExtension для предоставления поддержки экспорта политик. В результате System.ServiceModel.Description.MetadataExporterUdpTransportBindingElement интегрируется в формирование политики для любой привязки, содержащей UdpTransportBindingElement.

В IPolicyExportExtension.ExportPolicy добавьте утверждение для UDP и еще одно утверждение, если канал находится в режиме многоадресной рассылки. Это связано с тем, что режим мультикаста влияет на способ построения стека связи и, следовательно, должен быть согласован между обеими сторонами.

ICollection<XmlElement> bindingAssertions = context.GetBindingAssertions();
XmlDocument xmlDocument = new XmlDocument();
bindingAssertions.Add(xmlDocument.CreateElement(
UdpPolicyStrings.Prefix, UdpPolicyStrings.TransportAssertion, UdpPolicyStrings.UdpNamespace));
if (Multicast)
{
    bindingAssertions.Add(xmlDocument.CreateElement(
UdpPolicyStrings.Prefix, UdpPolicyStrings.MulticastAssertion,     UdpPolicyStrings.UdpNamespace));
}

Поскольку элементы пользовательской транспортной привязки отвечают за обработку адресации, реализация System.ServiceModel.Description.IPolicyExportExtension на UdpTransportBindingElement также должна обеспечивать экспорт соответствующих политических утверждений WS-Addressing, чтобы указать версию используемой WS-Addressing.

AddWSAddressingAssertion(context, encodingBindingElement.MessageVersion.Addressing);

Импорт политики

Чтобы расширить систему импорта политики, добавьте следующую конфигурацию в файл конфигурации для Svcutil.exe, как показано в файле Svcutil.exe.config:

<configuration>
  <system.serviceModel>
    <client>
      <metadata>
        <policyImporters>
          <extension type=" Microsoft.ServiceModel.Samples.UdpBindingElementImporter, UdpTransport" />
        </policyImporters>
      </metadata>
    </client>
  </system.serviceModel>
</configuration>

Затем мы реализуем System.ServiceModel.Description.IPolicyImportExtension из зарегистрированного класса (UdpBindingElementImporter). В IPolicyImportExtension.ImportPolicyэтом случае изучите утверждения в соответствующем пространстве имен и обработайте их для создания транспорта и проверки того, является ли он многоадресной рассылкой. Кроме того, удалите из списка утверждений привязки те, которые импортер обрабатывает. Опять же, при запуске Svcutil.exeсуществует два варианта интеграции:

  1. Укажите Svcutil.exe на наш файл конфигурации, используя /SvcutilConfig:<file>.

  2. Добавьте раздел конфигурации в Svcutil.exe.config в том же каталоге, что и Svcutil.exe.

Добавление пользовательского средства импорта стандартных привязок

Svcutil.exe и System.ServiceModel.Description.WsdlImporter тип по умолчанию распознают и импортируют предоставленные системой привязки. В противном случае связывание импортируется в виде экземпляра System.ServiceModel.Channels.CustomBinding. Чтобы задействовать Svcutil.exe и WsdlImporter, SampleProfileUdpBinding и UdpBindingElementImporter также действуют как пользовательские импортеры стандартных привязок.

Импортер специфических стандартных привязок реализует метод ImportEndpoint в интерфейсе System.ServiceModel.Description.IWsdlImportExtension для проверки экземпляра System.ServiceModel.Channels.CustomBinding, импортированного из метаданных, чтобы определить, мог ли он быть создан конкретной стандартной привязкой.

if (context.Endpoint.Binding is CustomBinding)
{
    Binding binding;
    if (transportBindingElement is UdpTransportBindingElement)
    {
        //if TryCreate is true, the CustomBinding will be replace by a SampleProfileUdpBinding in the
        //generated config file for better typed generation.
        if (SampleProfileUdpBinding.TryCreate(bindingElements, out binding))
        {
            binding.Name = context.Endpoint.Binding.Name;
            binding.Namespace = context.Endpoint.Binding.Namespace;
            context.Endpoint.Binding = binding;
        }
    }
}

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