WCF 项目应用连载[4] - 自定义配置 扩展ServiceHost - LServiceHost



在升级Lig服务之前,我们先升级两个类,以满足我们对WCF自定义配置的需求。



4.1 扩展 ServiceHost的背景

_____________________________________________________________


前面的创建的Lig系统中,我们对App.config没有作太详细的解释。你知道的,WCF是基于配置的编程。我们必要了解下我们的LigServer运行与LigClient运行正在依赖于哪些参数。对于Coder,我们习惯控制代码中出现的每一个变量,我们清楚我们的程序在做什么,因为这样能解决Bug。现在我们研究下App.config。

我们不能让这个App.config跟我们的exe文件在一起,这样的耦合是我们的不想要的,扩展ServiceHost的原因是:我们需要解除这样的限制。


好了。了解这点后。我们需要了解ServiceHost内部是如何操作App.config的,如果了解成功,我们自己就可以操作App.config而不是让程序自动去操作App.config



4.2 关于App.config

_____________________________________________________________


扩展ServiceHost之前,我们先看下App.config的结构
如你所见:
App.config核心参数由三部分构成,分别是服务、绑定与行为:

Services : 服务节点
Bindings : 绑定节点。为服务节点服务
Behaviors: 行为。为服务节点服务

关键点:
1)  绑定与行为都是为Services中的信息服务的。

2) 我们猜想ServiceHost操作了这三部分参数。如果我们能重写ServiceHost对配置的操作,我们自己不就可以操作App.config了吗?

3) 你猜对了。ServiceHost的确为继承者提供了这样的便利,我们可以通过重写ServiceHost中的

protected virtual void ApplyConfiguration();

虚方法,把Services中的节点信息,Bindings中的信息、Behaviors中的节点信息加入ServiceHost.Description属性中 就能能达成这一目的。


接下来我们要干的工作很明确了。我们要重写ApplyConfiguration


4.1 WCF服务端配置文件


原理清楚后,接来来就好办了:

1)   我们只需要写一个类继承ServiceHost.
2) 重写 ApplyConfiguration 把services/behaviors与bindings信息加入到ServiceHost的Description属性中
3)   并用 ExeConfigurationFileMap 修改App.config路径与文件名即可。



重写ServiceHost中ApplyConfiguration方法

#region Rewrite ApplyConfiguration

        /// <summary>
        /// Override ApplyConfiguration to load custom config file
        /// Attention : ConfigPath must be static variable according to the follow rules:
        /// 1. First run ApplyConfiguration of base class of ServiceHost
        /// 2. Second run constructor of EIPServiceHost itself
        /// </summary>
        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);
        }


添加services信息与bindings信息

/// <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;
        }

本节的源代码下载:

_____________________________________________________________


LServiceHost.cs

_____________________________________________________________




到此。大功告成。
我们已经扩展了ServiceHost,能自定义用ServiceHost创建的WCF服务了。。。


下一节我们将扩展ChannelFactory.........................................


参考引文:
[1] Artech.WCF全面解析[M].2012
[2] O'Reilly.WCF编程[M].2009
[3] Adnrew Trolesen.C#与.net3.5/4高级程序设计[M].2009/2013




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值