博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
自定义WCF的配置文件
阅读量:6708 次
发布时间:2019-06-25

本文共 4053 字,大约阅读时间需要 13 分钟。

原文地址:

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

<appSettings configSource="customAppSetting.config"/>

然后新建 customAppSetting.Config 文件:

在网站运行时,如果修改 Web.Config 文件会引起站点的重启,而修改 My.Config 文件则不会,同时也提高了配置文件的可读性。
然而WCF的配置上configSource是无效的,那么WCF如何自定义配置文件?
WCF的ServiceHost和ChannelFactory
分别提供了服务端和客户端的可扩展解决方案。下面针对这两个对象分别说明如何自定义服务端和客户端的配置文件。
1、服务端自定义配置文件:在ServiceHost的父类ServiceHostBase中,有一个和配置文件的加载密切相关的方法,它为:
protected virtual void ApplyConfiguration();
这个方法用于将应用程序配置文件中
节点下的配置信息,转换成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
和ChannelFactory
,ClientBase最终也是通过ChannelFactory
来构建Channel的
ChannelFactory
有两个方法为自定义配置文件提供解决方案:

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。代码下载

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

转载地址:http://hkilo.baihongyu.com/

你可能感兴趣的文章
VS2008编译工程缺少glaux库的解决方法
查看>>
Linux Crontab 定时任务 命令详解
查看>>
android APN cmnet切换cmwap
查看>>
Xcode环境变量列表
查看>>
openlava-4.0 安装教程(VMware/centos7)
查看>>
fineui实时监控(增、删、改)+CDC+长连接(一)
查看>>
mysql5.7的半同步复制
查看>>
Apache HttpClient (理解Http Client)
查看>>
Alibaba Sentinel 源码阅读(Part 2 LeapArray)
查看>>
Spring(三)装配Bean:手动装配Bean
查看>>
eclipse 调试时出现!MESSAGE Could not find bundle: or...
查看>>
ERROR Found the synthetic property @routerTransition
查看>>
js如何只获得Element自定义属性(自己手写在标签上的规定属性),不是自定义属性$(obj).attr("xx")...
查看>>
jquery support
查看>>
申奥动画长片名单出炉,动画质量大PK
查看>>
试图界定scala
查看>>
搞软件的一直会被人叫去修电脑 哎~ 发个安装方法会的可以自己装。
查看>>
Java并发编程实战
查看>>
Android App整体架构设计的思考
查看>>
2.NIO
查看>>