如何在代码中添加WCF自定义绑定元素扩展客户端,没有任何配置文件?

时间:2012-02-14 08:50:27

标签: wcf configuration wcf-binding servicebus

场合

我有一个客户端库,它使用Windows Azure AppFabric Service Bus 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>

3 个答案:

答案 0 :(得分:2)

这是现在已经过测试的解决方案。希望它能说清楚,问题究竟是什么,也许它可以帮助其他人解决类似的问题。对有时间调查问题的同事的信用。

解决方案是动态编辑配置并在任何层中添加对所需绑定元素扩展的引用(不带 app.config,或者不更改machine.config in客户机器):

        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 :(得分:1)

您可以通过编写自定义服务主机工厂来通过代码添加绑定元素扩展。类似的问题已经回答here

根据您的WCF服务类型,您只需在编写自定义服务主机工厂时继承相应的servicehostfactory类。例如如下所示:

  1. How to build a custom service host

  2. 如果构建REST WCF服务,请使用WebServiceHostFactory

  3. 如果构建WCF服务,请使用ServiceHostFactory

答案 2 :(得分:0)

此处没有配置的示例: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); 
        } 
    }