WCF Configuration - Split it out of app.config
Solution 1
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).
Solution 2
You can separate out your WCF configuration using configSource. Instructions here:
Another option is to configure your WCF services programatically.
Solution 3
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();
Solution 4
I found this article that may help you out. I have not tried it, but it seems fairly straightforward.
" 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. "
Solution 5
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 :-)
ZombieSheep
UK based .Net developer and gadget freak. My tweets | About reputation on StackOverflow
Updated on July 09, 2022Comments
-
ZombieSheep almost 2 years
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.
-
Admin almost 14 yearscheck System.ServiceModel.Configuration.ConfigurationChannelFactory
-
aruno over 11 yearswarning: as soon as you do this you lose intellisense which was greatly improved in .NET 4 even to the point of parsing your bindings and telling you things that are missing
-
-
marc_s over 15 yearsAre you sure?? I don't think this works - the "configSource" attribute isn't defined on all elements in the app.config/web.config, as far as I know....
-
davogones over 15 yearsThis doesn't work. You can only use configSource on sections, not sectionGroups.
-
Sailing Judo over 15 yearsThe only thing thats hardcoded above is the TCP binding. You can easily read all the other data from another source, which is what I do.
-
andriy almost 15 yearsThis only works on subsections of system.serviceModel (e.g. binding, client, etc.). It doesn't work on system.serviceModel itself.
-
Cheeso almost 15 yearsre: "less than simple." The custom ServiceHost code is available, more or less boilerplate.
-
RichardOD over 14 yearsYes- but surely that is good enough? weblogs.asp.net/cibrax/archive/2007/07/24/…
-
BozoJoe about 14 years
-
wmarquez about 13 yearsDocumentation on how this might be provided would be appreciated.
-
Kir over 12 yearsAgreed. This answer is too vague to be useful.
-
Noldorin over 12 years+1 for this. I actually dislike the WCF XML configuration on principle. Lots of boilerplate, incomprehensible options, and a very verbsoe syntax. Let me do it in code with Intellisense, I don't have to learn a new format, and all is good. I can still delegate things like port number to a custom setting anyway, as @SailingJudo hints. :-)