WCF配置 - 将其从app.config中分离出来

时间:2009-01-27 10:01:06

标签: .net wcf configuration app-config

我有一个特定的要求,即从主app.config文件中删除所有客户端WCF配置(< system.serviceModel>),并将其删除到单独的XML文件中。我希望看到的行为类似于使用File =“”指令在appSettings部分中提供的行为。事实上,我希望能够为每个消费的服务指定一个单独的文件......

我知道我可以构建一个自定义的ChannelBuilder工厂,它从XML文件(或其中一系列文件)中读取配置数据,但我更愿意仍然让客户端“自动发现”配置数据。

一些基本的Google搜索似乎暗示这是不可能的,但我想从SO中获取视图 - 这里有人知道我无法找到的内容吗? :)

  

编辑::

     Tim Scott和davogones都提出了一个可能的建议,但是依赖于将system.serviceModel部分的组件部分拆分为单独的文件。虽然这不是我想要的(我想分别定义每个服务及其相关元素,每个服务一个文件),但 是一个选项。我会调查并让你知道我的想法。

8 个答案:

答案 0 :(得分:17)

您可以使用configSource分离出您的WCF配置。说明:

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

另一种选择是以编程方式配置WCF服务。

答案 1 :(得分:6)

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

答案 2 :(得分:5)

我倾向于以编程方式配置我的所有服务设置。

我的客户并不是理解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 :(得分:3)

我发现这篇文章可能会帮到你。我没试过,但看起来相当简单。

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下的不同部分使用此属性,例如服务,行为或绑定。 “

答案 4 :(得分:2)

我一直渴望这样做 - 基本上甚至更进一步:将我的WCF配置放在数据库表中(因为我可以更改它 - 无法访问托管提供程序上的文件系统来更改配置文件: - (+)

不幸的是,这似乎不太简单.....

基本上,它归结为必须编写自己的自定义“ServiceHost”后代,它可以根据需要处理配置。

以下是loading WCF configuration from a custom config location的示例。

这可能会让你走?我仍然希望有一天我能够弄清楚“从数据库表中加载我的配置”.....只需要在工作中安静一周,我猜: - )

答案 5 :(得分:1)

System.ServiceModel.Configuration.ConfigurationChannelFactory等支持从System.Configuration.Configuration实例读取配置。这意味着您可以将<system.servicemodel ...内容放在专用文件中,而无需从web / app.config引用它。您可以拥有多个配置文件,每个客户端一个。

SharePoint 2010在其服务应用程序模型中过度使用了该模型,其中每个服务代理都从专用的.config中读取其设置,该配置不一定是web.config或app.config,甚至不会从那里引用。

答案 6 :(得分:0)

我的工作应用程序有点像你在这里谈论的那样。我们在多个项目中有多个WCF服务,所有配置信息都驻留在一个配置文件中。

我公司选择的解决方案是从配置文件中读取服务配置,然后根据读取的值以编程方式设置绑定,行为等。配置文件中的值不符合您在WCF服务中通常看到的配置内容 - 它被设计为帮助程序类可以在运行时轻松使用所有配置。

所有这一切,我根本不是这样做的忠实粉丝 - 过多的耦合正在发生并且它非常混乱。

但它确实表明它是可能的 - 在你的设计中考虑一件事。

答案 7 :(得分:0)

你可以这样做:

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

只需剪切您的服务模型部分并将其放在单独的文件中。您必须将整个部分放入单独的配置文件中;使用此方法,您不能让一个部分跨越多个文件AFAIK。