Как добавить пользовательские расширения элемента привязки WCF в коде без каких-либо файлов конфигурации? - PullRequest
1 голос
/ 14 февраля 2012

Ситуация

У меня есть клиентская библиотека, которая использует служебную шину Windows Azure AppFabric NetTcpRelayBinding для подключения к конечной точке.Клиентская библиотека размещается приложением, которое не обязательно является .NET-приложением.В любом случае, app.config исключен, что означает, что все должно быть сконфигурировано в коде.

Machine.config - один из вариантов, но лучше его избежать.Локальный пользовательский прокси-сервер или интерфейсный сервер могут быть другим вариантом, но я бы хотел сначала изучить этот вариант, прежде чем радикально изменить архитектуру.

Проблем с привязками системы нет, но у меня нетt не нашел или нашел решение, как добавить следующую конфигурацию в ChannelFactory в коде:

<extensions>
  <bindingElementExtensions>
   <add name="tcpRelayTransport" type="Microsoft.ServiceBus.Configuration.TcpRelayTransportElement, Microsoft.ServiceBus, Version=1.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
  </bindingElementExtensions>

  <bindingExtensions>
   <add name="netTcpRelayBinding" type="Microsoft.ServiceBus.Configuration.NetTcpRelayBindingCollectionElement, Microsoft.ServiceBus, Version=1.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
  </bindingExtensions>
 </extensions>

Ответы [ 3 ]

2 голосов
/ 21 марта 2012

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

Решением было динамическое редактирование конфигурации и добавление ссылки на необходимые Расширения связующего элемента ( без app.config в любом слое или без изменения machine.config на клиентских машинах ):

        var service = ServiceModelSectionGroup.GetSectionGroup(ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None));

        var tcpRelayTransportExtension = new ExtensionElement("tcpRelayTransport", "Microsoft.ServiceBus.Configuration.TcpRelayTransportElement, Microsoft.ServiceBus, Version=1.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
        var netTcpRelayTransportExtension = new ExtensionElement("netTcpRelayBinding", "Microsoft.ServiceBus.Configuration.NetTcpRelayBindingCollectionElement, Microsoft.ServiceBus, Version=1.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");

        if (service.Extensions.BindingElementExtensions.ContainsKey(tcpRelayTransportExtension.Name) == false)
        {
            service.Extensions.BindingElementExtensions.Add(tcpRelayTransportExtension);
        }

        if (service.Extensions.BindingElementExtensions.ContainsKey(netTcpRelayTransportExtension.Name) == false)
        {
            service.Extensions.BindingElementExtensions.Add(netTcpRelayTransportExtension);
        }

Спасибо всем, кто пытался помочь, хотя!

1 голос
/ 14 февраля 2012

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

В зависимости от типа службы WCF вам просто нужно наследовать соответствующий класс servicehostfactory при написании фабрики хостов настраиваемых служб. Например, как показано ниже:

  1. Как создать собственный хост службы

  2. При создании службы REST WCF используйте WebServiceHostFactory

  3. При создании службы WCF используйте ServiceHostFactory

0 голосов
/ 14 февраля 2012

Пример для этого без конфигурации доступен здесь: http://code.msdn.microsoft.com/windowsazure/Relayed-Messaging-Windows-0d2cede3

Ниже приведен фрагмент кода:

ChannelFactory<IEchoChannel> channelFactory = null; 
IEchoChannel channel = null; 
try 
{
    //Create a Behavior for the Credentials 
    TransportClientEndpointBehavior sharedSecretServiceBusCredential = new TransportClientEndpointBehavior(); 
    sharedSecretServiceBusCredential.TokenProvider = TokenProvider.CreateSharedSecretTokenProvider(issuerName, issuerSecret); 

    //Create a Channel Factory 
    channelFactory = new ChannelFactory<IEchoChannel>(new NetTcpRelayBinding(), new EndpointAddress(serviceAddress)); 
    channelFactory.Endpoint.Behaviors.Add(sharedSecretServiceBusCredential); 

    LogMessage("Opening channel to: {0}", serviceAddress); 
    channel = channelFactory.CreateChannel(); 
    channel.Open(); 

    LogMessage("Sending: {0}", echoTextBox.Text); 
    string echoedText = channel.Echo(echoTextBox.Text); 
    LogMessage("Received: {0}", echoedText); 
    echoTextBox.Text = string.Empty; 

    LogMessage("Closing channel"); 
    channel.Close(); 
    LogMessage("Closing factory"); 
    channelFactory.Close(); 
    } 
    catch (Exception ex) 
    { 
        LogMessage("Error sending: {0}<br/>{1}", ex.Message, ex.StackTrace.Replace("\n", "<br/>")); 

        // Close the channel and factory properly 
        if (channel != null) 
        { 
            CloseCommunicationObject(channel); 
        } 
        if (channelFactory != null) 
        { 
            CloseCommunicationObject(channelFactory); 
        } 
    } 
...