對於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 }