Конфигурация WCF - Разделите его из app.config

У меня есть специальное требование удалить всю конфигурацию WCF клиента (< system.serviceModel > ) из основного файла app.config и в отдельный XML файл. Поведение, которое я хотел бы видеть, аналогично тому, которое доступно в разделе appSettings, используя директиву File = "". Фактически, мне идеально хотелось бы указать отдельный файл для каждой потребляемой услуги...

Я знаю, что могу создать пользовательский ChannelBuilder factory, который считывает данные конфигурации из файла XML (или их серии), но я бы предпочел, чтобы клиентские данные были "автоматически обнаружены".

Некоторые основные поисковые запросы Google, похоже, предполагают, что это невозможно, но я хотел получить представление от SO - кто-нибудь знает что-то, чего я не смог найти?:)

Изменить::

Тим Скотт и davogones оба пришли к возможному предложению, но тот, который опирается на разделение разделов компонентов раздела system.serviceModel для разделения файлов. Хотя это не совсем то, что я ищу (я хотел бы определить каждую службу и связанные с ней элементы дискретно, по одному файлу на службу), это вариант. Я исследую и дам вам знать, что я думал.

Ответы

Ответ 1

У меня есть тенденция к программной настройке всех моих параметров службы.

Мои клиенты на самом деле не являются типом понимания XML и попросили меня сделать файлы конфигурации более похожими на старый стиль INI.

Это легко сделать (чтение кода файла INI не входит в комплект):

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

Поскольку мы можем настроить хост (и клиент, если на то пошло) программно, ничто не мешает вам предоставлять настройки любым способом (база данных, xml, сумасшедший текстовый файл и т.д.).

Ответ 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");
        }
    }
}

После этого класса просто используйте его, как обычно, для инициализации хоста службы

myServiceHost = new CustomServiceHost (ConfigFileName, typeof (QueryTree));

myServiceHost.Open();

Ответ 4

Я нашел эту статью, которая может помочь вам. Я не пробовал, но это кажется довольно простым.

http://weblogs.asp.net/cibrax/archive/2007/07/24/configsource-attribute-on-system-servicemodel-section.aspx

" Атрибут configSource был впервые представлен в .NET framework 2.0 для поддержки внешних файлов конфигурации. Этот атрибут можно добавить в любой раздел конфигурации, чтобы указать внешний файл для этого раздела.

К сожалению, группа section.serviceModel не поддерживает этот атрибут. Если вы попытаетесь добавить его, вы получите следующее исключение:

Невозможно указать атрибут 'configSource', потому что его имя начинается с зарезервированного префикса 'config' или 'lock'

Что я узнал, так это то, что вы можете использовать этот атрибут для разных разделов в разделе system.serviceModel, таких как службы, поведение или привязки. "

Ответ 5

Я очень хотел сделать то же самое - в принципе, еще один шаг: поместите мою конфигурацию WCF в таблицу базы данных (так как я могу ее изменить - не могу получить доступ к файловой системе моего хост-провайдера для изменения файлов конфигурации: - (+).

К сожалению, это кажется менее простым.....

В основном, это сводится к тому, чтобы написать собственный пользовательский потомок "ServiceHost", который может обрабатывать конфигурацию по мере необходимости.

Здесь приведен пример загрузка конфигурации WCF из пользовательского места конфигурации.

Это может вас заставить? Я все еще надеюсь, что когда-нибудь смогу выяснить, как загрузить мою конфигурацию из таблицы базы данных..... просто нужно тихо работать на неделю, я думаю: -)

Ответ 6

System.ServiceModel.Configuration.ConfigurationChannelFactory и все поддерживают чтение конфигурации из экземпляра System.Configuration.Configuration. Это означает, что вы можете поместить материал <system.servicemodel ... в выделенный файл, не ссылаясь на него из web/app.config. У вас может быть несколько конфигурационных файлов, по одному для каждого клиента.

SharePoint 2010 использует это чрезмерно в своей модели приложения-службы, где каждый прокси-сервер прочитывает свои настройки из выделенного .config, который не обязательно является web.config или app.config и даже не упоминается там.

Ответ 7

У меня есть приложение на работе, которое работает как то, о чем вы говорите. У нас есть несколько служб WCF для нескольких проектов, и вся их информация о конфигурации находится в одном файле конфигурации.

Решение, которое выбрала моя компания, состояло в том, чтобы прочитать конфигурацию службы из файла конфигурации, а затем программно настроить привязки, поведение и т.д. на основе прочитанных значений. Значения в файле конфигурации не соответствуют файлу конфигурации, который обычно отображается в службах WCF, - он был разработан для простого использования вспомогательным классом для выполнения всей конфигурации во время выполнения.

Все, что сказал, я не большой поклонник этого - вообще слишком много сцепления, и это довольно грязно.

Тем не менее, он показывает, что это возможно - об одном можно подумать в своем дизайне.

Ответ 8

Вы можете сделать следующее:

<system.serviceModel configSource="wcf.config"/>

Просто отделите раздел сервисной модели и поместите его в отдельный файл. Вам нужно будет поместить весь раздел в отдельный файл конфигурации; используя этот метод, вы не можете иметь раздел span несколько файлов AFAIK.