对于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 }

 

posted on 2018-07-28 15:12  高兴happy  阅读(170)  评论(0编辑  收藏  举报