zoukankan      html  css  js  c++  java
  • 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" %>
  • 相关阅读:
    jmeter----Linux上安装与使用
    Jmeter----客户端内存配置修改(Windows)
    Jmeter----生成HTML性能测试报告(Windows)
    nginx
    夜神模拟器 该网站的安全证书有问题 转载:https://bbs.yeshen.com/forum.php?mod=viewthread&tid=8864
    redis慢日志
    Nginx 转载:https://blog.csdn.net/yujing1314/article/details/107000737
    top 转载:https://mp.weixin.qq.com/s/kEY1U-CGIqQ2mKbr1aG8mA
    高可用
    shell 脚本 转载:https://mp.weixin.qq.com/s/rTsLIb2p-AE3oDPQXMQmLw
  • 原文地址:https://www.cnblogs.com/li150dan/p/9529313.html
Copyright © 2011-2022 走看看