对于WCF的宿主启动来讲,有好多方法,单独启动也很简单,能够根据业务须要来自由选择(单独启动方法这里就不作解释)app
对于业务服务比较多的时候,每每须要多个服务来承载系统,可是若是将服务启动单独写代码启动的话,这样就形成代码的耦合,增长服务,删除服务都须要对宿主程序进行修改编译,于是就须要一个批量启动的办法布局
如今着重整理一下理由反射批量启动spa
思路:一、自定义两个属性,用于接口和实现类,一个为接口属性,一个为实现类属性code
二、利用反射获取指定程序集的全部类文件,根据标记属性能够获取到那些为WCF接口和那些为WCF实现类blog
三、能够经过反射获取到实现类继承与什么接口继承
四、根据前三项便可将指定程序集的接口类和实现类对应接口
具体代码以下:ip
属性:string
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 }
接口和实现it
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 }