WCF重写ServiceHost,实现独立配置文件
有时我们需要将WCF的配置文件放在单独的配置文件中,而默认情况下WCF又是在web.config或app.config中去寻找服务配置。如果我们把配置文件放在另一个config文件中,如何让WCF知道呢?
答案就是重写ServiceHost。在重写中告诉WCF配置文件的路径。
public class MyServiceHost:ServiceHost
{
private string ConfigPath =System.AppDomain.CurrentDomain.BaseDirectory+ "MyApp.config"; public MyServiceHost(Type serviceType, params Uri[] baseAddresses) :
base(serviceType, baseAddresses)
{
} protected override void ApplyConfiguration()
{
// Check user config invalidation
if (!CheckConfigExist(ConfigPath))
{
// Use default config
base.ApplyConfiguration();
return;
}
//base.ApplyConfiguration();
// Use user config
ExeConfigurationFileMap execfgMap = new ExeConfigurationFileMap();
// Set user config FilePath
execfgMap.ExeConfigFilename = ConfigPath;
// Config info
Configuration cfg = ConfigurationManager.OpenMappedExeConfiguration(execfgMap,ConfigurationUserLevel.None);
// Gets all service model config sections
ServiceModelSectionGroup servicemodelSections = ServiceModelSectionGroup.GetSectionGroup(cfg); // Find serivce section matched with the name "this.Description.ServiceType.FullName"
if (!ApplySectionInfo(this.Description.ServiceType.FullName,servicemodelSections))
{
throw new Exception("ConfigApply Error : There is no endpoint existed in your config!! Please check your config file!");
}
this.ApplyMultiBehaviors(servicemodelSections); } /// <summary>
/// Check config file!
/// </summary>
/// <param name="configpath"></param>
/// <returns></returns>
private bool CheckConfigExist(string configpath)
{
if (string.IsNullOrEmpty(configpath)) return false;
if (!File.Exists(configpath)) return false;
return true;
} /// <summary>
/// Apply section info
/// </summary>
/// <param name="serviceFullName"></param>
/// <param name="servicemodelSections"></param>
/// <returns></returns>
private bool ApplySectionInfo(string serviceFullName, ServiceModelSectionGroup servicemodelSections)
{
// Check config sections (!including one section at least!)
if (servicemodelSections == null) return false;
// Service name can't be none!
if (string.IsNullOrEmpty(serviceFullName)) return false;
bool isElementExist = false;
foreach (ServiceElement element in servicemodelSections.Services.Services)
{
if (element.Name == serviceFullName)
{
// Find successfully & apply section info of config file
base.LoadConfigurationSection(element);
// Find service element successfully
isElementExist = true;
break;
}
}
return isElementExist;
} /// <summary>
/// Add behaviors
/// </summary>
/// <param name="servicemodelSections"></param>
/// <returns></returns>
private bool ApplyMultiBehaviors(ServiceModelSectionGroup servicemodelSections)
{
if (servicemodelSections == null) return false;
foreach (ServiceBehaviorElement element in servicemodelSections.Behaviors.ServiceBehaviors)
{
foreach (BehaviorExtensionElement behavior in element)
{
BehaviorExtensionElement behaviorEx = behavior;
object extention = behaviorEx.GetType().InvokeMember("CreateBehavior",
BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance,
null,
behaviorEx,
null);
if (extention == null) continue;
IServiceBehavior isb = (IServiceBehavior)extention;
//if (base.Description.Behaviors.Contains(isb)) break;
bool isbehaviorExisted = false;
foreach (IServiceBehavior i in base.Description.Behaviors)
{
if (i.GetType().Name == isb.GetType().Name)
{
isbehaviorExisted = true;
break;
}
}
if (isbehaviorExisted) break;
base.Description.Behaviors.Add((IServiceBehavior)extention);
}
}
return true;
} }
像上面那样,我们就把配置文件移到了MyApp.config。如果是控制台程序类的WCF服务就可以像下面那样来启动:
using (MyServiceHost host=new MyServiceHost(typeof(Service1)))
{
//... do something
host.Open();
}
而对于宿主是IIS的WCF服务,我们还需要再重写ServiceHostFactory:
public class MyServiceHostFactory : ServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
return new MyServiceHost(serviceType, baseAddresses);
}
}
然后在WCF服务的svc文件中,指定factory属性的值为我们重写的ServiceHostFactory:
<%@ ServiceHost Factory="WcfService1.MyServiceHostFactory" Language="C#" Debug="true" Service="WcfService1.Service1" CodeBehind="Service1.svc.cs" %>
WCF重写ServiceHost,实现独立配置文件的更多相关文章
- IOC容器Unity的使用及独立配置文件Unity.Config
[本段摘录自:IOC容器Unity 使用http://blog.csdn.net/gdjlc/article/details/8695266] 面向接口实现有很多好处,可以提供不同灵活的子类实现,增加 ...
- log4net保存到数据库系列二:独立配置文件中配置log4net
园子里面有很多关于log4net保存到数据库的帖子,但是要动手操作还是比较不易,从头开始学习log4net数据库日志一.WebConfig中配置log4net 一.WebConfig中配置log4ne ...
- 改进uwsgi启动脚本,使其支持多个独立配置文件
最近在研究flask,在架设运行环境的时候犯了难.因为我想把每个独立的应用像NGINX处理多个网站那样,每个应用单独一个配置文件.而网上流传的uwsgi启动脚本都只支持单个配置文件.虽然有文章说可以把 ...
- WCF 自托管、无配置文件实现jsonp(跨域)的访问
以下内容基于WCF4.0,本文将对比讨论配置文件方案和无配置文件方案的实现方式. WCF4.0加入了对RESTFU和标准终结点的支持,这为实现跨域提供了简单的方式. 一.有配置文件的情况: 首先我们先 ...
- Redis 哨兵节点之间相互自动发现机制(自动重写哨兵节点的配置文件)
Redis的哨兵机制中,如果是多哨兵模式,哨兵节点之间也是可以相互感知的,各种搜索之后出来的是千篇一律的一个基础配置文件,在配置当前哨兵节点的配置文件中,并没有配置其他哨兵节点的任何信息.如下是一个哨 ...
- log4net独立配置文件配置(winfrom)
log4net配置很多,具体配置步骤不细说,具体说出个人遇到的问题. 在winfrom和web应用程序中配置,在默认配置文件配置都没问题,因为EF也写在默认配置文件中,就会冲突解决办法就是将log4. ...
- WCF全面解析之三 使用配置文件启动WCF服务
知识:WCF地址.WCF绑定 Endpoint的配置 服务的三要素(ABC) A:Address 地址 有传输方式信息 B:Binding 怎么做(与地址的传输方式要匹配) C:Contract 做什 ...
- WCF的行为与异常-------配置文件说明
ServiceBehavior and OperationBehavior(这些都是应用在实现类上) http://msdn.microsoft.com/zh-cn/library/system.se ...
- [WCF REST] WebServiceHost 不依赖配置文件启动简单服务
最近用WPF启动 WCF REST 服务,发现app.config 配置好烦,简单一个exe 可以到处搬动,还非得带一个累赘配置,不小心丢了程序就跑不起来. 最后决定,砍去WCF配置项,用WebSer ...
随机推荐
- 关于JS的几点TIPS
作为前端基本工作每天都会用到JS...但是我们对JS真的都了解吗,或者说有什么tips是我们不知道的呢.. So..此文关于JS的几点tips..... 一:定时器(可传多个参数) 首先是一个一般的定 ...
- c++异常总结
堆栈辗转开解(stack-unwinding):如果一个函数中出现异常,在当前函数内即通过 try..catch 捕捉(且捕捉到)的话,可以继续往下执行:如果不捕捉(或未捕捉到)就会抛出(与通过 th ...
- Backbone事件模块源码分析
事件模块Backbone.Events在Backbone中占有十分重要的位置,其他模块Model,Collection,View所有事件模块都依赖它.通过继承Events的方法来实现事件的管理,可以说 ...
- [译]Exploring Angular 1.3: Binding to Directive Controllers
原文: http://blog.thoughtram.io/angularjs/2015/01/02/exploring-angular-1.3-bindToController.html Angul ...
- Android中设定背景图片平铺。
注:本文由Colin撰写,版权所有!转载请注明原文地址,谢谢合作! 在做Android开发时,我们常常需要为程序设定一个背景,但由于现在的Android设备尺寸不一,如果随便设置一个图片为背景,那么很 ...
- 关于Sublime text 的PHP编译环境配置的问题
前一段时间终于装上了传说中的代码编辑神器====>Sublime Text ,一打开便爱不释手,于是在网上找PHP的配置方案和插件,所有的一切都搞定了,可就是编译的时候没有显示,也没有提示,熬了 ...
- Ruby中Block, Proc, 和Lambda
Block Blocks就是存放一些可以被执行的代码的块,通常用do...end 或者 {}表示 例如: [1, 2, 3].each do |num| puts num end [1, 2, 3]. ...
- 资源URL地址记录
1. 如何搭建VPN服务器 http://www.360doc.com/content/11/0217/11/3084932_93749130.shtml http://www.softxp.net/ ...
- js验证姓名和身份证号
js验证真实姓名,是用的unicode字符的来进行匹配,而中国人的姓名长度一般都是2-4,所以重复匹配{2,4}次 1.js验证真实姓名 1 var regName =/^[\u4e00-\u9fa5 ...
- js搜索框输入提示(高效-ys8)
<style type="text/css"> .inputbox .seleDiv { border: 1px solid #CCCCCC; display: non ...