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

Ситуация

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

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

С системными привязками проблем нет, но я не понял и не нашел решения, как в коде добавить следующую конфигурацию в 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>

person Jemm    schedule 14.02.2012    source источник
comment
Взгляните на msdn.microsoft.com/en-us/ библиотека/, которая объясняет nettcprelaybinding с кодом C#   -  person Rajesh    schedule 14.02.2012
comment
@Rajesh В этом примере по-прежнему предполагается, что расширения привязки служебной шины (например, NetTcpRelayBinding) находятся в app.config или machine.config.   -  person Jemm    schedule 14.02.2012
comment
В этом случае ваш вопрос означает, как добавить привязкуElementExtensions через код С#?   -  person Rajesh    schedule 14.02.2012
comment
@Rajesh Да, я думаю, это было бы более точное название - исправлено.   -  person Jemm    schedule 14.02.2012


Ответы (3)


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

Решение заключалось в динамическом редактировании конфигурации и добавлении ссылки на необходимые расширения элементов привязки (без 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);
        }

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

person Jemm    schedule 21.03.2012

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

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

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

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

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

person Rajesh    schedule 14.02.2012
comment
Это хорошие примеры, но они предназначены для ServiceHost, на стороне сервера, что не является проблемой. Моя проблема на стороне клиента (ChannelFactory) - person Jemm; 14.02.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); 
        } 
    } 
person Abhishek Lal    schedule 14.02.2012
comment
Спасибо, но в этом образце все еще есть элемент bindingExtensions в файле web.config WebRole, который и является проблемой. - person Jemm; 15.02.2012