原文地址: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跨平台。扫下面的二维码或者收藏下面的二维码关注吧(长按下面的二维码图片、并选择识别图中的二维码)

自定义WCF的配置文件的更多相关文章

  1. WCF中配置文件解析

    WCF中配置文件解析[1] 2014-06-14 WCF中配置文件解析 参考 WCF中配置文件解析 返回 在WCF Service Configuration Editor的使用中,我们通过配置工具自 ...

  2. SharePoint 2013 中自定义WCF服务

    在使用SharePoint2013的时候,如果其他客户端 API 的组合不足,可以通过自定义 Web 服务扩展 SharePoint.默认情况下,SharePoint 2013 不仅支持创建自定义 A ...

  3. MVC + EFCore 完整教程19-- 最简方法读取json配置:自定义configuration读取配置文件

    问题引出 ASP.NET Core 默认将 Web.config移除了,将配置文件统一放在了 xxx.json 格式的文件中. 有Web.config时,我们需要读到配置文件时,一般是这样的: var ...

  4. Wcf 之 配置文件解析

    在WCF Service Configuration Editor的使用中,我们通过配置工具自动生成了WCF服务端的config文件.现在我们来看下这个配置文件各个标签的意义(解释在下面xml文件中的 ...

  5. WCF入门二[WCF的配置文件]

    一.概述 往往在很多项目中数据库连接字符串.变量和一些动态的加载类会写在配置文件中.WCF也会在配置文件中写入一些配置参数,比如服务的地址.服务用于发送和接收消息的传输和消息编码等,通过配置文件可以灵 ...

  6. WCF入门教程四[WCF的配置文件]

    一.概述 配置也是WCF编程中的主要组成部分.在 以往的.net应用程序中,我们会把DBConn和一些动态加载类及变量写在配置文件里.但WCF有所不同.他指定向客户端公开的服务,包括服务的地址. 服务 ...

  7. 无废话WCF入门教程四[WCF的配置文件]

    一.概述 配置也是WCF编程中的主要组成部分.在以往的.net应用程序中,我们会把DBConn和一些动态加载类及变量写在配置文件里.但WCF有所不同.他指定向客户端公开的服务,包括服务的地址.服务用于 ...

  8. 四、WCF的配置文件

    注:本文为学习摘抄,原文地址:http://www.cnblogs.com/iamlilinfeng/archive/2012/10/02/2710224.html 一.概述 配置也是WCF编程中的主 ...

  9. gradle 自定义插件 下载配置文件

    1.新建Gradle项目: 2.建立src/main/groovy目录,并添加如下代码: ConfigPlugin.groovy package com.wemall.config import or ...

随机推荐

  1. eclipse下:selenium+python自动化之Chrome driver

    1.下载chromedriver.exe文件: 2.下载的chromedriver.exe文件放置在chrome的安装目录下XXX\Chrome\Application\ ; 3.设置path环境变量 ...

  2. CentOS 7设置iptables防火墙开放proftpd端口

    由于ftp的被动模式是这样的,客户端跟服务器端的21号端口交互信令,服务器端开启21号端口能够使客户端登录以及查看目录.但是ftp被动模式用于传输数据的端口却不是21,而是大于1024的随机或配置文件 ...

  3. 关于UNION和UNION ALL的区别

    今天在运行程序的时候发现个问题,就是计算和的时候两条数据一样的话自动去除重复的,可是我这个程序需要重复的数据也算进来呀,然后就找原因,最后在sql语句中找到了是union和union all的问题,简 ...

  4. .net版ckeditor配置水印功能(转)

    本文简单讲解ckfinder控件给上图片加水印效果. 1.将ckfinder/plugins/watermark/bin/Debug目录下的CKFinder_Watermark.dll和CKFinde ...

  5. Spring+AOP+Log4j 用注解的方式记录指定某个方法的日志

    一.spring aop execution表达式说明 在使用spring框架配置AOP的时候,不管是通过XML配置文件还是注解的方式都需要定义pointcut"切入点" 例如定义 ...

  6. 第六篇、WebSphere8.5 (商业级服务器)大规模集群

    一.前言 上一篇中讲述了WebSphere的安装与应用,该版本的WAS一般都用于开发测试(有些小应用生产环境下也会用到),在生产中绝大部份使用的WebSphere Application Server ...

  7. access_token的获取2

    概述 access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token.开发者需要进行妥善保存. access_token的存储至少要保留512个字符空间.acces ...

  8. python读写Excel文件的函数--使用xlrd/xlwt

    python中读取Excel的模块或者说工具有很多,如以下几种: Packages 文档下载 说明 openpyxl Download | Documentation | Bitbucket  The ...

  9. git extrad_addons 部署说明

    注册一个git账号 : 网址:  https://github.com/ 1:安装git   sudo apt-get install git 2:  b把urc扩展占模块pull下来    cd   ...

  10. bzoj2395: [Balkan 2011]Timeismoney

    Description      有n个城市(编号从0..n-1),m条公路(双向的),从中选择n-1条边,使得任意的两个城市能够连通,一条边需要的c的费用和t的时间,定义一个方案的权值v=n-1条边 ...