• 自定义WCF的配置文件


    原文地址:http://www.cnblogs.com/shanyou/archive/2008/12/02/1346298.html 

    WCF的承载既可以通过编码实现,也能够通过配置实现.而且使用配置,更有利于日后的维护和扩展。我们经常会碰到这样的一个场景:需要把WCF的配置信息放在一个单独的文件中,这种情况经常出现在需要为自己开发的服务配置,需要采用独立的配置文件,而不是只能放到app.config/web.config中。.NET提供了一种机制是通过ConfigSource。例如在asp.net的在站点的默认 Web.Config 文件中使用:

    <appSettings configSource="customAppSetting.config"/>

    然后新建 customAppSetting.Config 文件:

    <?xml version="1.0" encoding="utf-8"?>
    <appSettings>
    <add key="IsDev" value="True"/>
    </appSettings>
    在网站运行时,如果修改 Web.Config 文件会引起站点的重启,而修改 My.Config 文件则不会,同时也提高了配置文件的可读性。
    然而WCF的配置上configSource是无效的,那么WCF如何自定义配置文件?
    WCF的ServiceHost和ChannelFactory<T>分别提供了服务端和客户端的可扩展解决方案。下面针对这两个对象分别说明如何自定义服务端和客户端的配置文件。
    1、服务端自定义配置文件:在ServiceHost的父类ServiceHostBase中,有一个和配置文件的加载密切相关的方法,它为:
    protected virtual void ApplyConfiguration();
    这个方法用于将应用程序配置文件中<system.serviceModel>节点下的配置信息,转换成WCF的具体服务设置。那么重写这个方法,代码如下:

    /// <summary>
    /// override ApplyConfiguration to load config from custom file
    /// </summary>
    protected override void ApplyConfiguration()
    {
    //get custom config file name by our rule: config file name = ServiceType.Name
    var myConfigFileName = this.Description.ServiceType.FullName;
    //get config file path
    string dir = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
    string myConfigFilePath = System.IO.Path.Combine(dir, myConfigFileName + ".config");
    if (!System.IO.File.Exists(myConfigFilePath))
    {
    base.ApplyConfiguration();
    return;
    }
    var configFileMap = new System.Configuration.ExeConfigurationFileMap();
    configFileMap.ExeConfigFilename = myConfigFilePath;
    var config = System.Configuration.ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigurationUserLevel.None);
    var serviceModel = System.ServiceModel.Configuration.ServiceModelSectionGroup.GetSectionGroup(config);
    if (serviceModel == null)
    {
    base.ApplyConfiguration();
    return;
    }
    foreach (ServiceElement serviceElement in serviceModel.Services.Services)
    {
    if (serviceElement.Name == this.Description.ServiceType.FullName)
    {
    LoadConfigurationSection(serviceElement);
    return;
    }
    }
    throw new Exception("there is no service element match the description!");
    }
    }
    }

    2、WCF的客户端自定义配置文件,WCF可以通过两种方式构建代理,ClientBase<T>和ChannelFactory<T>,ClientBase最终也是通过ChannelFactory<T>来构建Channel的
    ChannelFactory<T>有两个方法为自定义配置文件提供解决方案:

    protected virtual void ApplyConfiguration(string configurationName);
    protected abstract ServiceEndpoint CreateDescription();

    ApplyConfiguration方法和ServiceHost的ApplyConfiguration方法的功能类似,但是有一点不同的是需要和CreateDescription交互。其实ApplyConfiguration并不是客户端代理这里所要关注的地方,我们只需要关注CreateDescription就可以了。

    ChannelFactory<T>的方法CreateDescription实现上是从默认配置文件(缺省AppDomain的配置文件),所以我们通过重写这个方法就可以实现从外部文件加载配置。

    /// <summary>

    /// Loads the serviceEndpoint description from the specified configuration file

    /// </summary>

    /// <returns></returns>

    protected override ServiceEndpoint CreateDescription()

    {

       ServiceEndpoint serviceEndpoint = base.CreateDescription();

       ExeConfigurationFileMap map = new ExeConfigurationFileMap();

       map.ExeConfigFilename = this.configurationPath;

       Configuration config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);

       ServiceModelSectionGroup group = ServiceModelSectionGroup.GetSectionGroup(config);

       ChannelEndpointElement selectedEndpoint = null;

       foreach (ChannelEndpointElement endpoint in group.Client.Endpoints)

       {

          if (endpoint.Contract == serviceEndpoint.Contract.ConfigurationName)

          {

            selectedEndpoint = endpoint;

            break;

          }

        }

        if (selectedEndpoint != null)

        {

          if (serviceEndpoint.Binding == null)

          {

            serviceEndpoint.Binding = CreateBinding(selectedEndpoint.Binding, group);

          }

          if (serviceEndpoint.Address == null)

          {

            serviceEndpoint.Address = new EndpointAddress(selectedEndpoint.Address, GetIdentity(selectedEndpoint.Identity), selectedEndpoint.Headers.Headers);

          }

          if (serviceEndpoint.Behaviors.Count == 0 && selectedEndpoint.BehaviorConfiguration != null)

          {

            AddBehaviors(selectedEndpoint.BehaviorConfiguration, serviceEndpoint, group);

          }

          serviceEndpoint.Name = selectedEndpoint.Contract;

        }

        return serviceEndpoint;

    }

    具体的实现可以参看例子代码,这个例子WCF sdk的例子ICalculator。代码下载CustomChannel.zip

    欢迎大家关注微信号opendotnet,微信公众号名称:dotNET跨平台。扫下面的二维码或者收藏下面的二维码关注吧(长按下面的二维码图片、并选择识别图中的二维码)

  • 相关阅读:
    SQL学习之计算字段的用法与解析
    SQL学习之用通配符进行数据过滤
    SQL学习之高级数据过滤
    SQL学习之空值(Null)检索
    JavaScript之arguements对象学习
    django配置数据库
    django创建项目
    django安装
    Django套用现成模板,导入css,js,images等文件
    Nvidia显卡安装驱动
  • 原文地址:https://www.cnblogs.com/niaowo/p/4727578.html
Copyright © 2020-2023  润新知