Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WCF Configuration - Split it out of app.config

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.

like image 239
ZombieSheep Avatar asked Jan 27 '09 10:01

ZombieSheep


People also ask

Is app config and web config are same?

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.

Does app config get compiled?

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.

What is Servicemodel in web config?

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.

Where are app config files stored?

Windows uses the %APPDATA% directory for user specific application configuration files.


2 Answers

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.

like image 122
davogones Avatar answered Sep 16 '22 16:09

davogones


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();

like image 25
Samir Avatar answered Sep 19 '22 16:09

Samir