Loading WCF Client Configuration from Different Files with ConfigurationChannelFactory

One
pain point with configuration that WCF developers have run into in
previous versions of the framework is the limitation that WCF clients
can only use the hosting executable’s configuration file. This can be
problematic for clients that need to call multiple services because the
configuration for all of these services would have to be mashed together
in one big configuration file. This can also be a problem for client
libraries: since libraries don’t have configuration files, every
executable that uses the library needs to provide it with the right
configuration in its own configuration file.

Fortunately, this restriction has been lifted in WCF 4.0 with the introduction of ConfigurationChannelFactory. This new class allows you to create clients that can take in any Configuration object to configure your client. This means that you’re no longer limited to using the App.config for your executable. To demonstrate this new class, let’s say you have a client that needs to call out to a web service that returns stock information and another web service that returns weather information.

In WCF 4.0, you can do this:

Configuration stockConfiguration = ConfigurationManager.OpenMappedExeConfiguration(new ExeConfigurationFileMap { ExeConfigFilename = @"C:\Temp\StockClient.config"}, ConfigurationUserLevel.None);

ConfigurationChannelFactory<StockQuoteSoap> stockChannelFactory = new ConfigurationChannelFactory<StockQuoteSoap>("StockQuoteSoap", stockConfiguration, null);

StockQuoteSoap stockClient = stockChannelFactory.CreateChannel();

GetQuoteResponse stockResponse = stockClient.GetQuote(new GetQuoteRequest { Body = new GetQuoteRequestBody { symbol = "MSFT" } });

Console.WriteLine(stockResponse.Body.GetQuoteResult);

stockChannelFactory.Close();

Configuration weatherConfiguration = ConfigurationManager.OpenMappedExeConfiguration(new ExeConfigurationFileMap { ExeConfigFilename = @"C:\Temp\WeatherClient.config" }, ConfigurationUserLevel.None);

ConfigurationChannelFactory<GlobalWeatherSoap> weatherChannelFactory = new ConfigurationChannelFactory<GlobalWeatherSoap>("GlobalWeatherSoap", weatherConfiguration, null);

GlobalWeatherSoap weatherClient = weatherChannelFactory.CreateChannel();

GetWeatherResponse weatherResponse = weatherClient.GetWeather(new GetWeatherRequest { Body = new GetWeatherRequestBody { CityName = "Paris", CountryName = "France" } });

Console.WriteLine(weatherResponse.Body.GetWeatherResult);

weatherChannelFactory.Close();

In this example, two separate client configuration files are located at C:\Temp\StockClient.config and C:\Temp\WeatherClient.config and we’re able to use both in the very same method! For each service, we first load up a configuration object, then pass that configuration object to the constructor for ConfigurationChannelFactory, and finally call the service and print out the results. It's that easy.