Конфигурация WCF - разделить его из app.config - PullRequest
16 голосов
/ 27 января 2009

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

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

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

Редактировать ::

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

Ответы [ 8 ]

17 голосов
/ 28 января 2009

Вы можете выделить свою конфигурацию WCF, используя configSource. Инструкции здесь:

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

Другим вариантом является программная настройка служб WCF.

6 голосов
/ 31 декабря 2010
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 = новый CustomServiceHost (ConfigFileName, typeof (QueryTree));

myServiceHost.Open ();

5 голосов
/ 27 января 2009

У меня есть склонность к программной настройке всех моих настроек сервиса.

Мои клиенты на самом деле не из тех, кто понимает 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 голосов
/ 25 июня 2010

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

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

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

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

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

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

2 голосов
/ 27 января 2009

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

.

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

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

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

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

1 голос
/ 25 июня 2010

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

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

0 голосов
/ 28 января 2009

Вы можете сделать так:

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

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

0 голосов
/ 27 января 2009

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

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

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

Это, однако, показывает, что это возможно - это одна вещь, о которой нужно подумать в вашем дизайне.

...