有时我们需要将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,实现独立配置文件的更多相关文章

  1. IOC容器Unity的使用及独立配置文件Unity.Config

    [本段摘录自:IOC容器Unity 使用http://blog.csdn.net/gdjlc/article/details/8695266] 面向接口实现有很多好处,可以提供不同灵活的子类实现,增加 ...

  2. log4net保存到数据库系列二:独立配置文件中配置log4net

    园子里面有很多关于log4net保存到数据库的帖子,但是要动手操作还是比较不易,从头开始学习log4net数据库日志一.WebConfig中配置log4net 一.WebConfig中配置log4ne ...

  3. 改进uwsgi启动脚本,使其支持多个独立配置文件

    最近在研究flask,在架设运行环境的时候犯了难.因为我想把每个独立的应用像NGINX处理多个网站那样,每个应用单独一个配置文件.而网上流传的uwsgi启动脚本都只支持单个配置文件.虽然有文章说可以把 ...

  4. WCF 自托管、无配置文件实现jsonp(跨域)的访问

    以下内容基于WCF4.0,本文将对比讨论配置文件方案和无配置文件方案的实现方式. WCF4.0加入了对RESTFU和标准终结点的支持,这为实现跨域提供了简单的方式. 一.有配置文件的情况: 首先我们先 ...

  5. Redis 哨兵节点之间相互自动发现机制(自动重写哨兵节点的配置文件)

    Redis的哨兵机制中,如果是多哨兵模式,哨兵节点之间也是可以相互感知的,各种搜索之后出来的是千篇一律的一个基础配置文件,在配置当前哨兵节点的配置文件中,并没有配置其他哨兵节点的任何信息.如下是一个哨 ...

  6. log4net独立配置文件配置(winfrom)

    log4net配置很多,具体配置步骤不细说,具体说出个人遇到的问题. 在winfrom和web应用程序中配置,在默认配置文件配置都没问题,因为EF也写在默认配置文件中,就会冲突解决办法就是将log4. ...

  7. WCF全面解析之三 使用配置文件启动WCF服务

    知识:WCF地址.WCF绑定 Endpoint的配置 服务的三要素(ABC) A:Address 地址 有传输方式信息 B:Binding 怎么做(与地址的传输方式要匹配) C:Contract 做什 ...

  8. WCF的行为与异常-------配置文件说明

    ServiceBehavior and OperationBehavior(这些都是应用在实现类上) http://msdn.microsoft.com/zh-cn/library/system.se ...

  9. [WCF REST] WebServiceHost 不依赖配置文件启动简单服务

    最近用WPF启动 WCF REST 服务,发现app.config 配置好烦,简单一个exe 可以到处搬动,还非得带一个累赘配置,不小心丢了程序就跑不起来. 最后决定,砍去WCF配置项,用WebSer ...

随机推荐

  1. \r,\n,\r\n的区别

    http://www.studyofnet.com/news/285.html \n是换行,英文是New line,表示使光标到行首\r是回车,英文是Carriage return,表示使光标下移一格 ...

  2. map 与 unordered_map

    两者效率对比: #include <iostream> #include <string> #include <map> #include <unordere ...

  3. Ubuntu 下apache2开启rewrite隐藏index.php

    为了实现 http://www.example.com/route/route 而不是 http://www.example.com/index.php/route/route 需要开启apache2 ...

  4. Word有用的快捷键

      1.shift+上下左右,可以用键盘从当前光标位置选择文本.可以配合各种其他导航键,比如ctrl+上下左右,Home, End, PageUp/Down. 2.选择文本后,按F2,光标会自动变成虚 ...

  5. 实现Android的不同精度的定位(基于网络和GPS)

    解决方案: 实现Android的不同精度的定位(基于网络和GPS) Android中的定位服务的相关类基本上都在android.location包中,其中位置服务管理器(LocationManager ...

  6. Divide Two Integers

    视频讲解  http://v.youku.com/v_show/id_XMTY1MTAyODM3Ng==.html int 范围: Integer.MIN_VALUE => -214748364 ...

  7. thinkphp的CURD操作

    增 //a字段是主键 $data['b'] = 'bbb'; $data['c'] = 'c'; $new_id = M('test')->data($data)->add(); //ec ...

  8. ES6中Arguments和Parameters用法解析

    原文链接 译文 ECMAScript 6 (也称 ECMAScript 2015) 是ECMAScript 标准的最新版本,显著地完善了JS中参数的处理方式.除了其它新特性外,我们还可以使用rest参 ...

  9. HTTP头部详解

    因为之后的HTTP头注入要学习这些所以就看了.觉得很不错,算是学习前的科普. <HTTP头部详解>转载自:http://www.cnblogs.com/lcamry/p/5763040.h ...

  10. Android使用Unity导致Activity被销毁的解决办法

    由于需要在Android中使用Unity(Android的Activity会继承Unity提供的UnityPlayerActivity),可能是第三方的原因退出Unity后就导致Android整个应用 ...