WCF寄宿windows服务二

如果有很多WCF服务需要寄宿,需要额外做一些工作:
总体思路是:先把这些WCF服务的程序集打包,然后利用反射加载各个WCF服务的程序集,按顺序一个一个寄宿。
先来看看我们需要寄宿的WCF服务:

实现步骤:
1、配置文件中打包这些WCF程序集信息。

2、需要自定义配置节点以及实现读取自定义配置节点的方法。
在configSections节点增加配置:

 <section name="ValidServices"
             type="Mdtit.XXX.Mall.Hosting.ValidServicesSection, Mdtit.XXX.Mall.Hosting" />

配置处理类实现如下:

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;
using System.ServiceModel.Description;
using System.Text;
using Mdtit.XXX.Mall.Common;

namespace Mdtit.XXX.Mall.Hosting
{
    /// <summary>
    /// Custom configuration section for valid service setting
    /// </summary>
    internal class ValidServicesSection : ConfigurationSection
    {
        [ConfigurationProperty("Services")]
        public ValidServiceCollection ValidServices
        {
            get { return this["Services"] as ValidServiceCollection; }
        }
    }

    /// <summary>
    /// Custom configuration element collection for valid service setting
    /// </summary>
    internal class ValidServiceCollection : ConfigurationElementCollection
    {
        protected override ConfigurationElement CreateNewElement()
        {
            return new ValidService();
        }

        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((ValidService)element).Type;
        }
    }

    /// <summary>
    /// Custom configuration element for valid service setting
    /// </summary>
    internal class ValidService : ConfigurationElement
    {
        [ConfigurationProperty("Type")]
        public string Type
        {
            get
            {
                return (string)this["Type"];
            }
        }
    }
}

3、windows服务的Main函数

static class Program
{
	/// <summary>
	/// The main entry point for the application.
	/// </summary>
	static void Main()
	{
		ServiceBase[] ServicesToRun;
		ServicesToRun = new ServiceBase[] 
		{ 
			new XXXService() 
		};
		ServiceBase.Run(ServicesToRun);
	}
}

4、windows服务类:XXXService

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using Mdtit.XXX.Mall.Hosting;
using Mdtit.XXX.Mall.Common;
using System.ServiceModel;

namespace Mdtit.XXX.Mall.Hosting.Service
{
    public partial class XXXService : ServiceBase
    {
        /// <summary>
        /// All avalilable services.
        /// </summary>
        static List<ServiceHost> _allHosts = new List<ServiceHost>();

        public XXXService()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
            try
            {
                ServiceManager.StartAllValidServices();
                LogHelper.LogInformation("All WCF services started.");
            }
            catch (ApplicationException ex)
            {
                LogHelper.LogInformation(ex.Message);
            }
        }

        protected override void OnStop()
        {
            try
            {
                ServiceManager.CloseAllServices();
                LogHelper.LogInformation("All WCF services stopped.");
            }
            catch (ApplicationException ex)
            {
                LogHelper.LogInformation(ex.Message);
            }
        }
    }
}

其中,ServiceManager.StartAllValidServices() 和 ServiceManager.CloseAllServices()是用来批量处理WCF服务的。

5、ServiceManager类实现如下:

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Reflection;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Text;

using Mdtit.XXX.Mall.Common;

namespace Mdtit.XXX.Mall.Hosting
{
    /// <summary>
    /// Helper class to start/stop services
    /// </summary>
    internal class ServiceManager
    {
        /// <summary>
        /// Container for all valid services
        /// </summary>
        static List<ServiceHost> _AllHosts = new List<ServiceHost>();

        /// <summary>
        /// Start all valid services.
        /// </summary>
        public static void StartAllValidServices()
        {
            string entryLocation = Assembly.GetEntryAssembly().Location;

            Configuration conf = ConfigurationManager.OpenExeConfiguration(entryLocation);

            ValidServicesSection validServiceSettings
                = ConfigurationManager.GetSection("ValidServices") as ValidServicesSection;

            if (validServiceSettings != null)
            {
                foreach (ValidService validService in validServiceSettings.ValidServices)
                {
                    string typeToLoad = validService.Type;

                    // Load the assembly dynamic
                    string assemblyName = typeToLoad.Substring(typeToLoad.IndexOf(',') + 1);
                    Assembly.Load(assemblyName);

                    Type svcType = Type.GetType(typeToLoad);
                    if (svcType == null)
                    {
                        string errInfo = string.Format("Invalid Service Type "{0}" in configuration file.",
                            typeToLoad);

                        LogHelper.LogError(errInfo);
                        throw new ApplicationException(errInfo);
                    }
                    else
                    {
                        OpenHost(svcType);
                    }
                }
            }
            else
            {
                throw new ApplicationException("Application configuration for WCF services not found!");
            }
        }

        /// <summary>
        /// Create a host for a specified wcf service;
        /// </summary>
        /// <param name="t"></param>
        private static void OpenHost(Type t)
        {
            ServiceHost host = new ServiceHost(t);

            host.Opened += new EventHandler(hostOpened);
            host.Closed += new EventHandler(hostClosed);
            host.Open();

            _AllHosts.Add(host);
        }

        /// <summary>
        /// Close all services
        /// </summary>
        public static void CloseAllServices()
        {
            foreach (ServiceHost host in _AllHosts)
            {
                if (host.State != CommunicationState.Closed)
                {
                    host.Close();
                }
            }
        }

        /// <summary>
        /// Event handler for host opened
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void hostOpened(object sender, EventArgs e)
        {
            ServiceDescription svcDesc = ((ServiceHost)sender).Description;

            string svcName = svcDesc.Name;
            StringBuilder allUri = new StringBuilder();
            foreach (ServiceEndpoint endPoint in svcDesc.Endpoints)
            {
                allUri.Append(endPoint.ListenUri.ToString());
            }

            LogHelper.LogInformation(string.Format("Service "{0}" started with url: {1}",
                svcName, allUri.ToString()));
        }

        /// <summary>
        /// Event handler for host closed
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void hostClosed(object sender, EventArgs e)
        {
            ServiceDescription svcDesc = ((ServiceHost)sender).Description;

            string svcName = svcDesc.Name;

            LogHelper.LogInformation(string.Format("Service "{0}" stopped.", svcName));
        }
    }
}

6、开始寄宿
以管理员身份运行我们前面写好的windows服务程序:

结果:

原文地址:https://www.cnblogs.com/zhaow/p/8288843.html