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



我的应用程序在运行时更改端点设置,并将更改保留到配置文件。但是,当我创建新的服务代理实例时,端点设置是更新之前的设置。如何强制代理获取新设置?

您需要检测您的配置文件是否已更新,无论是您的主 app.config/web.config 还是您通过 configSource 使用的任何外部配置文件。

如果检测到更改,则需要刷新 system.serviceModel 配置部分:

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

现有的ChannelsChannelFactories不会接受更改,因此需要关闭它们并创建新的更改。

以下示例演示了此操作:

[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>

如果您以其他方式管理终端节点配置,则可以手动更新任何ChannelFactory实例,因为您可以访问终端节点和绑定属性。

最新更新