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

时间:2013-10-14 14:38:07

标签: wcf configuration-files

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

1 个答案:

答案 0 :(得分:3)

您需要检测您的配置文件是否已更新为主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实例,因为您可以访问端点和绑定属性。