I have a specific requirement to remove all client WCF configuration (<system.serviceModel>) out of the main app.config file, and into a separate XML file. The behaviour I would like to see is similar to that available in the appSettings section using the File="" directive. In fact, I'd ideally like to be able to specify a separate file for each consumed service...
I know I can build a custom ChannelBuilder factory that reads config data from an XML file (or a series of them), but I would prefer to still have the config data "auto-discovered" by the client.
Some basic Google searches seem to suggest this is not possible, but I wanted to get the view from SO - does anyone here know something I haven't been able to find? :)
Edit ::
Tim Scott and davogones both came up with a possible suggestion, but one which relies on splitting the component sections of the system.serviceModel section out to separate files. Although this isn't quite what I'm looking for (I'd like to define each service and its associated elements discretely, one file per service), it is an option. I'll investigate and let you know what I thought.
When using Windows Forms or WPF etc, then you have the app. config which also stores ConnectionStrings. So yes they are similar but have different purposes.
Now you might be wondering what happens behind the scenes. Well, when you compile your application, the compiler actually copies the app. config file to the output folder, but gives it another name: When you start your application (ConsoleApp1.exe in our example), the matching config file will be loaded too.
servicemodel element, there are behaviors, bindings and services. We can define various behaviors like endpoint behaviors and servicebehaviors under the behaviors element. In the binding section different bindings like basicHttpBinding, wsHttpBinding etc. In our example we define basicHttpBinding.
Windows uses the %APPDATA% directory for user specific application configuration files.
You can separate out your WCF configuration using configSource. Instructions here:
http://weblogs.asp.net/cibrax/archive/2007/07/24/configsource-attribute-on-system-servicemodel-section.aspx
Another option is to configure your WCF services programatically.
using System;
using System.Configuration;
using System.IO;
using System.ServiceModel;
using System.ServiceModel.Configuration;
namespace ConsoleHost
{
public class CustomServiceHost : ServiceHost
{
public CustomServiceHost(string customConfigPath, Type serviceType,
params Uri[] baseAddresses)
{
CustomConfigPath = customConfigPath;
var collection = new UriSchemeKeyedCollection(baseAddresses);
InitializeDescription(serviceType, collection);
}
public string CustomConfigPath { get; private set; }
protected override void ApplyConfiguration()
{
if (string.IsNullOrEmpty(CustomConfigPath) ||
!File.Exists(CustomConfigPath))
{
base.ApplyConfiguration();
}
else
{
LoadConfigFromCustomLocation(CustomConfigPath);
}
}
void LoadConfigFromCustomLocation(string configFilename)
{
var filemap = new ExeConfigurationFileMap
{
ExeConfigFilename = configFilename
};
Configuration config = ConfigurationManager.
OpenMappedExeConfiguration(filemap, ConfigurationUserLevel.None);
var serviceModel = ServiceModelSectionGroup.GetSectionGroup(config);
bool loaded = false;
foreach (ServiceElement se in serviceModel.Services.Services)
{
if (se.Name == Description.ConfigurationName)
{
LoadConfigurationSection(se);
loaded = true;
break;
}
}
if (!loaded)
throw new ArgumentException("ServiceElement doesn't exist");
}
}
}
After this class just use it as you would normally use it to initialize the service host
myServiceHost = new CustomServiceHost(ConfigFileName, typeof(QueryTree));
myServiceHost.Open();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With