简体   繁体   English

WCF服务代理不会从配置文件刷新绑定设置

[英]WCF service proxy doesn't refresh binding settings from config file

My application changes end-point settings at run-time and persists the changes to config file. 我的应用程序在运行时更改端点设置,并将更改保留到配置文件。 But when I create a new service proxy instance, the end-point settings are the ones that were before the update. 但是当我创建一个新的服务代理实例时,端点设置是更新之前的设置。 How do I force the proxy to get new settings? 如何强制代理获取新设置?

You will need to detect if your configuration file has been updated be it your main app.config / web.config or any external configuration file you are using via configSource. 您需要检测配置文件是否已更新为主app.config / web.config或您通过configSource使用的任何外部配置文件。

If a change is detected you will need to refresh the system.serviceModel configuration section: 如果检测到更改,则需要刷新system.serviceModel配置部分:

ConfigurationManager.RefreshSection("system.serviceModel/client");

Existing Channels and ChannelFactories will not pick up the changes so they will need to be closed and new ones created. 现有ChannelsChannels ChannelFactories不会接收更改,因此需要关闭它们并创建新的更改。

The following example shows this in action: 以下示例显示了此操作:

[TestFixture]
class When_trying_to_change_service_endpoints_on_the_fly
{
    [Test]
    public void Should_use_the_new_endpoint()
    {
        var someService1 = Substitute.For<ISomeWebService>();
        var someService2 = Substitute.For<ISomeWebService>();

        var serviceHost1 = CreateServiceHost(someService1, new Uri("http://localhost:50001"));
        var serviceHost2 = CreateServiceHost(someService2, new Uri("http://localhost:50002"));

        serviceHost1.Open();
        serviceHost2.Open();

        UpdateEndpointInConfig(new Uri("http://localhost:50001"));

        var channelFactory = new ChannelFactory<ISomeWebService>("TestReloadConfig");

        var channel1 = channelFactory.CreateChannel();
        channel1.ServiceMethod();
        ((IChannel)channel1).Close();

        channelFactory.Close();

        UpdateEndpointInConfig(new Uri("http://localhost:50002"));

        channelFactory = new ChannelFactory<ISomeWebService>("TestReloadConfig");

        var channel2 = channelFactory.CreateChannel();
        channel2.ServiceMethod();
        ((IChannel)channel2).Close();

        serviceHost1.Close();
        serviceHost2.Close();

        someService1.Received(1).ServiceMethod();
        someService2.Received(1).ServiceMethod();
    }

    private static void UpdateEndpointInConfig(Uri endpointAddress)
    {
        var configFile = new ExeConfigurationFileMap();
        configFile.ExeConfigFilename = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None).FilePath;

        var config = ConfigurationManager.OpenMappedExeConfiguration(configFile, ConfigurationUserLevel.None);

        var serviceModelConfig = (ServiceModelSectionGroup) config.GetSectionGroup("system.serviceModel");
        serviceModelConfig.Client.Endpoints[0].Address = endpointAddress;

        config.Save();

        ConfigurationManager.RefreshSection("system.serviceModel/client");
    }

    private ServiceHost CreateServiceHost<TService>(TService service, Uri baseUri)
    {
        var serviceHost = new ServiceHost(service, new Uri[0]);

        serviceHost.Description.Behaviors.Find<ServiceDebugBehavior>().IncludeExceptionDetailInFaults = true;
        serviceHost.Description.Behaviors.Find<ServiceBehaviorAttribute>().InstanceContextMode = InstanceContextMode.Single;

        serviceHost.AddServiceEndpoint(typeof(TService), new BasicHttpBinding(), baseUri);

        return serviceHost;
    }
}

[ServiceContract]
public interface ISomeWebService
{
    [OperationContract]
    void ServiceMethod();
}
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <client>
      <endpoint address="http://localhost:50000" binding="basicHttpBinding" contract="Junk.ISomeWebService" name="TestReloadConfig" />
    </client>
  </system.serviceModel>
</configuration>

If you managed the endpoint configurations another way you could update any ChannelFactory instance manually as you have access to the Endpoint and Binding properties. 如果您以另一种方式管理端点配置,则可以手动更新任何ChannelFactory实例,因为您可以访问Endpoint和Binding属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM