代码之家  ›  专栏  ›  技术社区  ›  ZombieSheep

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

  •  16
  • ZombieSheep  · 技术社区  · 17 年前

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

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

    一些基本的谷歌搜索似乎表明这是不可能的,但我想从SO那里了解情况——这里有人知道我找不到的东西吗? :)

    编辑::

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

    8 回复  |  直到 17 年前
        1
  •  17
  •   davogones    17 年前

    您可以使用configSource分离WCF配置。此处说明:

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

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

        2
  •  6
  •   Nick Spreitzer    11 年前
    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=新的自定义服务主机(ConfigFileName,类型为(QueryTree));

    myServiceHost。Open();

        3
  •  5
  •   Sailing Judo    17 年前

    我倾向于用程序配置我的所有服务设置。

    我的客户不是真正理解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、疯狂文本文件等)提供设置。

        4
  •  3
  •   Boris    15 年前

    我发现这篇文章可能对你有所帮助。我没有尝试过,但它似乎相当简单。

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

        5
  •  2
  •   Tim Cooper    14 年前

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

    不幸的是,这似乎并不简单。....

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

    以下是一个示例 loading WCF configuration from a custom config location .

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

        6
  •  1
  •   ToxicAvenger ToxicAvenger    15 年前

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

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

        7
  •  0
  •   Tad Donaghe    17 年前

    我在工作中有一个应用程序,它的工作原理有点像你在这里说的。我们在多个项目中有多个WCF服务,它们的所有配置信息都位于一个配置文件中。

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

    尽管如此,我根本不喜欢这样做——耦合太多,而且很混乱。

    不过,这确实表明这是可能的——这是你在设计中需要考虑的一件事。

        8
  •  0
  •   Tim Scott    17 年前

    你可以这样做:

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

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