2013-10-14 1 views

답변

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 인스턴스를 업데이트 할 수있는 다른 방법을 관리합니다.

관련 문제