zoukankan      html  css  js  c++  java
  • 利用反射,批量启动WCF服务

    对于WCF的宿主启动来说,有好多方法,单独启动也很简单,可以根据业务需要来自由选择(单独启动方法这里就不做解释)

    对于业务服务比较多的时候,往往需要多个服务来承载系统,但是如果将服务启动单独写代码启动的话,这样就造成代码的耦合,增加服务,删除服务都需要对宿主程序进行修改编译,因而就需要一个批量启动的办法

    现在着重整理一下理由反射批量启动

    思路:1、自定义两个属性,用于接口和实现类,一个为接口属性,一个为实现类属性

       2、利用反射获取指定程序集的所有类文件,根据标记属性可以获取到那些为WCF接口和那些为WCF实现类

       3、可以通过反射获取到实现类继承与什么接口

       4、根据前三项即可将指定程序集的接口类和实现类对应

    具体代码如下:

    属性:

     1 namespace ESTM.WCF.Service
     2 {
     3     //标记此特性的为WCF服务接口
     4     public class ServiceInterfaceAttribute : Attribute
     5     {
     6     }
     7 
     8     //标记此特性的为WCF服务接口实现类
     9     public class ServiceClassAttribute : Attribute
    10     {
    11     }
    12 }

    接口和实现

     1 namespace ESTM.WCF.Service
     2 {
     3     /// <summary>
     4     /// 工厂布局模块接口契约
     5     /// </summary>
     6     [ServiceInterface]
     7     [ServiceContract]
     8     public interface IFactoryLayoutWCFService
     9     {
    10         [OperationContract]
    11         List<DTO_TM_PLANT> GetAllPlant();        
    12     }
    13 }
     1 namespace ESTM.WCF.Service
     2 {
     3     [ServiceClass]
     4     public class FactoryLayoutWCFService : IFactoryLayoutWCFService
     5     {
     6         public List<DTO_TM_PLANT> GetAllPlant()
     7         {
     8             throw new NotImplementedException();
     9         }
    10     }
    11 }

    WCF 批量启动帮助类

     1 namespace ESTM.WCF.Service
     2 {
     3     public class Bootstrapper
     4     {
     5         private string strBaseServiceUrl = ConfigurationManager.AppSettings["ServiceUrl"].ToString();
     6 
     7         //启动所有的服务
     8         public void StartServices()
     9         {
    10             //1.读取此程序集里面的有服务契约的接口和实现类
    11             var assembly = Assembly.Load(typeof(Bootstrapper).Namespace);
    12             //获取当前程序集的所有类文件(包括接口和类)
    13             var lstType = assembly.GetTypes();
    14             //存储当前程序集的所有接口
    15             var lstTypeInterface = new List<Type>();
    16             //存储当前程序集的所有接口实现类
    17             var lstTypeClass = new List<Type>();
    18 
    19             foreach (var oType in lstType)
    20             {
    21                 //2.通过接口上的特性取到需要的接口和实现类
    22                 var lstCustomAttr = oType.CustomAttributes;
    23                 //如果当前类上面存在属性标签
    24                 if (lstCustomAttr.Count() <= 0)
    25                 {
    26                     continue;
    27                 }
    28                 //获取第一个属性标签,并且判断是否相等于接口自定义属性
    29                 //如果相等,则为接口
    30                 var oInterfaceServiceAttribute = lstCustomAttr.FirstOrDefault(x => x.AttributeType.Equals(typeof(ServiceInterfaceAttribute)));
    31                 if (oInterfaceServiceAttribute != null)
    32                 {
    33                     lstTypeInterface.Add(oType);
    34                     continue;
    35                 }
    36                 //如果相等,则为类
    37                 var oClassServiceAttribute = lstCustomAttr.FirstOrDefault(x => x.AttributeType.Equals(typeof(ServiceClassAttribute)));
    38                 if (oClassServiceAttribute != null)
    39                 {
    40                     lstTypeClass.Add(oType);
    41                 }                
    42             }
    43 
    44             //3.启动所有服务
    45             foreach (var oInterfaceType in lstTypeInterface)
    46             {
    47                 //在实现类集合中   获取由当前 Type 实现或继承的特定接口。
    48                 var lstTypeClassTmp = lstTypeClass.Where(x => x.GetInterface(oInterfaceType.Name) != null).ToList();
    49                 if (lstTypeClassTmp.Count <= 0)
    50                 {
    51                     continue;
    52                 }
    53                 //如果当前类获取到的接口等于遍历的接口名称,则匹配成功,
    54                 if(lstTypeClassTmp[0].GetInterface(oInterfaceType.Name).Equals(oInterfaceType))
    55                 {
    56                     var oTask = Task.Factory.StartNew(() =>
    57                     {
    58                         OpenService(strBaseServiceUrl + "/" + oInterfaceType.Name, oInterfaceType, lstTypeClassTmp[0]);
    59                     });
    60                 }
    61             }            
    62         }
    63 
    64         //通过服务接口类型和实现类型启动WCF服务
    65         private void OpenService(string strServiceUrl, Type typeInterface, Type typeclass)
    66         {
    67             Uri httpAddress = new Uri(strServiceUrl);
    68             using (ServiceHost host = new ServiceHost(typeclass))//需要添加System.SystemModel这个dll。。。。CSOAService这个为实现ICSOAService的实现类,WCF真正的实现方法再这个类里面
    69             {
    70                 ///////////////////////////////////////添加服务节点///////////////////////////////////////////////////
    71                 host.AddServiceEndpoint(typeInterface, new WSHttpBinding(), httpAddress);//ICSOAService这个为向外暴露的接口
    72                 if (host.Description.Behaviors.Find<ServiceMetadataBehavior>() == null)
    73                 {
    74                     ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
    75                     behavior.HttpGetEnabled = true;
    76                     behavior.HttpGetUrl = httpAddress;
    77                     host.Description.Behaviors.Add(behavior);
    78                 }
    79                 host.Opened += delegate
    80                 {
    81                     Console.ForegroundColor = ConsoleColor.Green;
    82                     Console.WriteLine("服务启动成功。服务地址:" + strServiceUrl);
    83                 };
    84 
    85                 host.Open();
    86                 while (true)
    87                 {
    88                     Console.ReadLine();
    89                 }
    90             }
    91         }
    92     }
    93 }
  • 相关阅读:
    pb数据窗口下拉数据窗口列的排序(翻译)
    pb重复行的检查(翻译)
    pb数据窗口如何按当前列的值过滤下拉数据窗口(翻译)
    PB中通过对象名获取对象并获取对象下的子对象
    有关医嘱中的bid,qd等执行频率
    pb数据窗口新增的列编辑后不会分行
    words
    here.less
    Springboot use tomcat JNDI
    genemotion
  • 原文地址:https://www.cnblogs.com/happygx/p/9382083.html
Copyright © 2011-2022 走看看