zoukankan      html  css  js  c++  java
  • WCF重写ServiceHost,实现独立配置文件

    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
  • 相关阅读:
    使用MobaXterm远程连接Ubuntu,启动Octave,界面不能正常显示
    ABP .Net Core 日志组件集成使用NLog
    ABP .Net Core Entity Framework迁移使用MySql数据库
    ABP前端使用阿里云angular2 UI框架NG-ZORRO分享
    阿里云 Angular 2 UI框架 NG-ZORRO介绍
    Visual Studio 2019 Window Form 本地打包发布猫腻
    VS Code + NWJS(Node-Webkit)0.14.7 + SQLite3 + Angular6 构建跨平台桌面应用
    ABP .Net Core 调用异步方法抛异常A second operation started on this context before a previous asynchronous operation completed
    ABP .Net Core To Json序列化配置
    .Net EF Core数据库使用SQL server 2008 R2分页报错How to avoid the “Incorrect syntax near 'OFFSET'. Invalid usage of the option NEXT in the FETCH statement.”
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3653207.html
Copyright © 2011-2022 走看看