原文地址: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. Java-strurs总结

    这里是自己对自学的struts2 的一个整体 的脉络进行的一个概括,需要学习哪些东西,注重哪些东西: struts2 是主流框架SSH 中的一个"S" ,准备MVC开发标准的一个框 ...

  2. Core Animation系列之CADisplayLink(转)

    转自 http://www.tuicool.com/articles/meMVR3 一直以来都想好好学习下CoreAnimation,奈何涉及的东西太多,想要一次性全部搞定时间上不允许,以后会断断续续 ...

  3. AVAudioSession

    AVAudioSession类由AVFoundation框架引入.每个IOS应用都有一个音频会话.这个会话可以被AVAudioSession类的sharedInstance类方法访问,如下: AVAu ...

  4. [LeetCode OJ] Gas Station

    问题描述: There are N gas stations along a circular route, where the amount of gas at station i is gas[i ...

  5. SGU 156. Strange Graph(欧拉路)

    时间限制:0.25s 空间限制:6M 题目描述 让我们想象一个无向图G=<V,E>.如果边(u,v)在边集E中,那么我们就说两个顶点u和v是邻接点.在这种情况下,我们也说u是v的一个邻接点 ...

  6. SGU 171.Sarov zones

    简单的贪心.优先weight最大的,优先匹配Q值大的地区 code #include <iostream> #include <algorithm> #include < ...

  7. spl_autoload_register()和__autoload()

    关于spl_autoload_register()和__autoload() 看两者的用法: //__autoload用法 function __autoload($classname) {     ...

  8. CentOS 忘记root密码,解决方法

    1.开机后,在倒数5秒结束前,按下任意键 2.在显示centos...的那个界面下,按e键(edit) 3.会出现三行的界面,选择中间 kernel...那行,然后按e键 4.在接着出现的那个界面最后 ...

  9. [r]How To Use Git To Create A Key

    怎样生成公钥(via) 工作流程 安装设置 git 下载最新版本的git http://git-scm.com/downloads 当你安装完成git的时候,你需要简单的配置一下,打开终端: 用户名 ...

  10. 在uboot上创建菜单

    一.原理 菜单其实就是一个uboot中的命令,和其他的命令没有什么差别.  uboot启动时,如果进入uboot命令模式,先运行这个命令,就会打印出一个菜单界面. 在uboot的命令模式,通过键入“m ...