zoukankan      html  css  js  c++  java
  • Host多个WCF服务(Selfhost)Start ServiceHosts for all configured Services

    Important Update: The originally presented code only works if the service is defined in the same assembly which hosts the service (because the name="" attribute in <service> may not contain the assembly name of the service). See at the end of the article for a slightly different version which works in all cases --- but which involves adding a second config file.

    As WCF has reached RC1 stage, I find myself cleaning up a few bits of older WCF code. While playing around with it, I always found myself having to start more and more ServiceHosts for different configurations. The following snippet iterates over all <service> entries in configuration/system.serviceModel and opens a ServiceHost for each of them.
    Update: Added code to close all services.

    using System;
    using System.Collections.Generic;
    using System.Reflection;
    using System.Configuration;
    using System.ServiceModel.Configuration;
    using System.ServiceModel;
    public class ServiceHostGroup
    {
        static List<ServiceHost> _hosts = new List<ServiceHost>();
        private static void OpenHost(Type t)
        {
            ServiceHost hst = new ServiceHost(t);
            hst.Open();
            _hosts.Add(hst);
        }
        public static void StartAllConfiguredServices()
        {
            Configuration conf =
              ConfigurationManager.OpenExeConfiguration(Assembly.GetEntryAssembly().Location);
            ServiceModelSectionGroup svcmod =
              (ServiceModelSectionGroup)conf.GetSectionGroup("system.serviceModel");
            foreach (ServiceElement el in svcmod.Services.Services)
            {
                Type svcType = Type.GetType(el.Name);
                if (svcType == null)
                  throw new Exception("Invalid Service Type " + el.Name + " in configuration file.");
                OpenHost(svcType);
            }
        }
        public static void CloseAllServices()
        {
            foreach (ServiceHost hst in _hosts)
            {
                hst.Close();
            }
        }
    }

    As mentioned above, I have in the meantime learned (after long and hard fighting against the "this service has no non-metadata endpoints"-exception), that the name="" attribute in <service> must not contain an assembly name. I guess I have been too used to Remoting configuration files after all ;-). To still get dynamic service configuration without code changes, I've added a second configuration file called services.xml and changed the code for ServiceHostGroup to the following:
    Services.XML:

    <configuredServices>
      <service type="ServiceImplementation.ArticleService, ServiceImplementation" />
    </configuredServices>

    ServiceHostBase.cs:

    using System;
    using System.Collections.Generic;
    using System.Reflection;
    using System.Configuration;
    using System.ServiceModel.Configuration;
    using System.ServiceModel;
    using System.Xml;
    using System.Xml.Serialization;
    using System.IO;
    public class ServiceHostGroup
    {
      static List<ServiceHost> _hosts = new List<ServiceHost>();
      private static void OpenHost(Type t)
      {
        ServiceHost hst = new ServiceHost(t);
        Type ty = hst.Description.ServiceType;
        hst.Open();
        _hosts.Add(hst);
      }
      public static void StartAllConfiguredServices()
      {
        ConfiguredServices services = ConfiguredServices.LoadFromFile("services.xml");
        foreach (ConfiguredService svc in services.Services)
        {
          Type svcType = Type.GetType(svc.Type);
          if (svcType == null) throw new Exception("Invalid Service Type " + svc.Type + " in configuration file.");
          OpenHost(svcType);
        }
      }
      public static void CloseAllServices()
      {
        foreach (ServiceHost hst in _hosts)
        {
          hst.Close();
        }
      }
    }
    [XmlRoot("configuredServices")]
    public class ConfiguredServices
    {
      public static ConfiguredServices LoadFromFile(string filename)
      {
        if (!File.Exists(filename)) return new ConfiguredServices();
        XmlSerializer ser = new XmlSerializer(typeof(ConfiguredServices));
        using (FileStream fs = File.OpenRead(filename))
        {
          return (ConfiguredServices) ser.Deserialize(fs);
        }
      }
      [XmlElement("service", typeof(ConfiguredService))]
      public List<ConfiguredService> Services = new List<ConfiguredService>();
    }
    public class ConfiguredService
    {
      [XmlAttribute("type")]
      public string Type;
    }

  • 相关阅读:
    第二阶段:团队开发Fooks第七天
    第二阶段:团队开发Fooks第六天
    第二阶段:团队开发Fooks第五天
    【POI每日题解 #9】SKA-Piggy Banks
    ac自动机
    【POI每日题解 #8】DYN-Dynamite
    vector
    【POI每日题解 #7】TES-Intelligence Test
    【POI每日题解 #6】KRA-The Disks
    DP
  • 原文地址:https://www.cnblogs.com/ddlzq/p/2029671.html
Copyright © 2011-2022 走看看