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

你可能感兴趣的:(WCF)