I have a specific requirement to remove all client WCF configuration (
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();
I have an application at work that works kind of like what you're talking about here. We have multiple WCF services across multiple projects and all of their configuration information resides in a single config file.
The solution my company chose was to read the service configuration out of the config file and then programmatically set up the bindings, behavior, etc based on the values read. The values in the config file don't conform to the config stuff you usually see in WCF services - it was designed to be easily used by a helper class to do all the configuration at run time.
All that said, I'm not a big fan of doing that at all - too much coupling going on and it's pretty messy.
It does, though, show that it's possible - it's one thing to think about in your design.
You can do like this:
<system.serviceModel configSource="wcf.config"/>
Just cut your service model section out and put it in a separate file. You will have to put the whole section into the separate config file; using this method you cannot have a section span multiple files AFAIK.
I've been longing to do the same - basically even one step further: put my WCF config in a database table (since I can change that - can't access the file system on my hosted provider to change config files :-().
Unfortunately, this seems less than simple.....
Basically, it boils down to having to write your own custom "ServiceHost" descendant which can handle the configuration as needed.
Here's an example of loading WCF configuration from a custom config location.
This might get you going? I'm still hoping I'll be able to figure out the "loading my config from a database table" some day..... just need to quiet week at work, I guess :-)
I found this article that may help you out. I have not tried it, but it seems fairly straightforward.
http://weblogs.asp.net/cibrax/archive/2007/07/24/configsource-attribute-on-system-servicemodel-section.aspx
" The configSource attribute was firstly introduced in .NET framework 2.0 to support external configuration files. This attribute can be added to any configuration section to specify an external file for that section.
Unfortunately, the system.serviceModel section group does not support this attribute. If you try to add it, you will receive the following exception:
The attribute 'configSource' cannot be specified because its name starts with the reserved prefix 'config' or 'lock'
What I found out is that you can use this attribute on the different sections under system.serviceModel such as services, behaviors or bindings. "
I have a tendency to programatically configure all my service settings.
My clients aren't really the type to understand XML and have asked me make configuration files more like the old INI style.
This is easy to do (reading INI file code not included):
// create the URI which is used as the service endpoint
Uri tcpBaseAddress = new Uri(
string.Format("net.tcp://{0}:{1}",
LocalIPAddress.ToString(), GeneralPortNumber));
// create the net.tcp binding for the service endpoint
NetTcpBinding ntcBinding = new NetTcpBinding();
ntcBinding.Security.Mode = SecurityMode.None;
System.ServiceModel.Channels.Binding tcpBinding = ntcBinding;
// create the service host and add the endpoint
Host = new ServiceHost(typeof(WordWarService), tcpBaseAddress);
Since we can configure the host (and client, for that matter) programatically there is nothing keeping you from supplying the settings in any manner you choose (database, xml, crazy text file, etc).