博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
WCF自寄宿
阅读量:5173 次
发布时间:2019-06-13

本文共 10929 字,大约阅读时间需要 36 分钟。

WCF很早就出现了,然而我感受到能够让新手重点去学习WCF而不是WebService是最近两年。我相信大部分人初步了解WCF的时候会很痛苦,尤其是生成代理类,以及配置的问题。我本人其实比较讨厌配置编程,但喜欢轻量配置,因此也一直研究如何自己定义配置节点,去让WCF服务识别,然后重量级ABC操作由编码来完成。下面,我将会提供一个我本人用于学习其他知识需要使用WCF时的开发模式,另外说明,为了更好的说明,我将提供的都是精简版本,并不适合用于测试生产的例子。

1.定义适合自己的配置

1 public class WCFServiceElement : ConfigurationElement 2 { 3         [ConfigurationProperty(name: "ServiceName", IsRequired = false)] 4         public string ServiceName 5         { 6             get 7             { 8                 return (base["ServiceName"] as string); 9             }10             set11             {12                 base["ServiceName"] = value;13             }14         }15 16         [ConfigurationProperty(name: "ServiceAssembly", IsRequired = false)]17         public string ServiceAssembly18         {19             get20             {21                 return (base["ServiceAssembly"] as string);22             }23             set24             {25                 base["ServiceAssembly"] = value;26             }27         }28 29         [ConfigurationProperty(name: "InterfaceServiceName", IsRequired = false)]30         public string InterfaceServiceName31         {32             get33             {34                 return (base["InterfaceServiceName"] as string);35             }36             set37             {38                 base["InterfaceServiceName"] = value;39             }40         }41 42         [ConfigurationProperty(name: "InterfaceServiceAssembly", IsRequired = false)]43         public string InterfaceServiceAssembly44         {45             get46             {47                 return (base["InterfaceServiceAssembly"] as string);48             }49             set50             {51                 base["InterfaceServiceAssembly"] = value;52             }53         }54 55         [ConfigurationProperty(name: "IPAddress", IsRequired = false)]56         public string IPAddress57         {58             get59             {60                 return (base["IPAddress"] as string);61             }62             set63             {64                 base["IPAddress"] = value;65             }66         }67 68         [ConfigurationProperty(name: "Binding", IsRequired = false)]69         public string Binding70         {71             get72             {73                 return (base["Binding"] as string);74             }75             set76             {77                 base["Binding"] = value;78             }79         }80 }
View Code
1 public class WCFServicesElementCollection : ConfigurationElementCollection 2     { 3         protected override ConfigurationElement CreateNewElement() 4         { 5             ConfigurationElement _element = new WCFServiceElement(); 6             return _element; 7         } 8  9         protected override object GetElementKey(ConfigurationElement element)10         {11             WCFServiceElement _element = (WCFServiceElement)element;12             return _element.ServiceName;13         }14 15         protected override string ElementName16         {17             get18             {19                 return "WCFService";20             }21         }22 23         public override ConfigurationElementCollectionType CollectionType24         {25             get26             {27                 return ConfigurationElementCollectionType.BasicMap;28             }29         }30 }
View Code
1 public class WCFServiceSection : ConfigurationSection 2 { 3         [ConfigurationProperty(name: "", IsDefaultCollection = true, IsRequired = false)] 4         public WCFServicesElementCollection WCFServices 5         { 6             get 7             { 8                 return (base[""] as WCFServicesElementCollection); 9             }10             set11             {12                 base[""] = value;13             }14         }15 }
View Code
1 
2
3
4
5
6
7
13
14
15
View Code

这里注意的是configSections一定要放在第一行,这个倒是听让人无语的。当然配置可以用自己希望方式配置,我这里提供一个简单的思路。

2.定义适合自己的WCFServerConfigurationManagement

1 public abstract class WCFServerConfigurationManagement 2 { 3         private static HybridDictionary _Collection = new HybridDictionary(); 4  5         public static void Register() 6         { 7             WCFServiceSection section = ConfigurationManager.GetSection("WCFServices") as WCFServiceSection; 8             if (null == section) 9             {10                 throw new NullReferenceException("未能识别WCFServices,请确认configSections配置节点");11             }12 13             _Collection.Clear();14 15             foreach (WCFServiceElement element in section.WCFServices)16             {17                 Assembly assemblyInterfaceService = Assembly.Load(element.InterfaceServiceAssembly);18                 Assembly assemblyService = Assembly.Load(element.ServiceAssembly);19 20                 Type typeInterface = assemblyInterfaceService.ExportedTypes.FirstOrDefault(type => type.Name.Equals(element.InterfaceServiceName));21                 Type typeImplement = assemblyService.ExportedTypes.FirstOrDefault(type => type.Name.Equals(element.ServiceName));22 23                 if (null == typeInterface && null == typeImplement)24                 {25                     throw new NullReferenceException("无法加载服务");26                 }27 28                 ServiceHost _NewHost = new ServiceHost(typeImplement);29                 Binding binding = CreateBinding(element.Binding);30                 _NewHost.AddServiceEndpoint(typeInterface, binding, element.IPAddress);31                 32                 _NewHost.Opened += (sender, e) =>33                 {34 #if DEBUG35                     Console.WriteLine($"服务:{element.ServiceName} 已经开启.");36 #endif37                 };38                 _NewHost.Open();39             }40         }41 42         public static Binding CreateBinding(string bindingType)43         {44             Binding _Binding = default(Binding);45             switch (bindingType)46             {47                 case "BasicHttpBinding":48                     _Binding = new BasicHttpBinding();49                     break;50                 case "WSHttpBinding":51                     _Binding = new WSHttpBinding();52                     break;53                 case "WS2007HttpBinding":54                     _Binding = new WS2007HttpBinding();55                     break;56                 default:57                     throw new ArgumentNullException("根据接口名称无法匹配绑定类型");58             }59 60             return _Binding;61         }62 }
View Code

这里主要用来根据配置动态配置WCF ServiceHost 和 Binding 的.然后再您的Custom Host 里面调用如下:

1 class Program2 {3         static void Main(string[] args)4         {5             WCFServerConfigurationManagement.Register();6 7             Console.ReadLine();8         }9 }
View Code

3.定义适合自己的WCFClientConfigurationManagement

1 public abstract  class WCFClientConfigurationManagement 2 { 3         private static HybridDictionary _Collection = new HybridDictionary(); 4  5         public static void Register() 6         { 7             WCFServiceSection section = ConfigurationManager.GetSection("WCFServices") as WCFServiceSection; 8             if (null == section) 9             {10                 throw new NullReferenceException("未能识别WCFServices,请确认configSections配置节点");11             }12 13             _Collection.Clear();14 15             foreach (WCFServiceElement element in section.WCFServices)16             {17                 _Collection.Add(element.InterfaceServiceName , element);18             }19         }20 21         public static Binding CreateBinding(string serviceName)22         {23             Binding _Binding = default(Binding);24             WCFServiceElement element = _Collection[serviceName] as WCFServiceElement;25             if (null == element)26             {27                 Register();28                 element = _Collection[serviceName] as WCFServiceElement;29                 if (null == element)30                 {31                     throw new NullReferenceException("可能配置出现严重错误,根据接口名称无法获取配置文件信息.");32                 }33             }34 35             switch (element.Binding)36             {37                 case "BasicHttpBinding":38                     _Binding = new BasicHttpBinding();39                     break;40                 case "WSHttpBinding":41                     _Binding = new WSHttpBinding();42                     break;43                 case "WS2007HttpBinding":44                     _Binding = new WS2007HttpBinding();45                     break;46                 default:47                     throw new ArgumentNullException("根据接口名称无法匹配绑定类型");48             }49 50             return _Binding;51         }52 53         public static EndpointAddress CreateAddress(string serviceName)54         {55             WCFServiceElement element = _Collection[serviceName] as WCFServiceElement;56             if (null == element)57             {58                 Register();59                 element = _Collection[serviceName] as WCFServiceElement;60                 if (null == element)61                 {62                     throw new NullReferenceException("可能配置出现严重错误,根据接口名称无法获取配置文件信息.");63                 }64             }65 66             EndpointAddress _Address = new EndpointAddress(element.IPAddress);67             return _Address;68         }69 }
View Code

这里主要用来根据配置动态配置WCF Client 和 Binding 的。然后再您的客户端以及配置文件注册如下(我这里提供的是ASP.NET MVC 5 的环境):

1 public class MvcApplication : HttpApplication 2 { 3         protected void Application_Start() 4         { 5             AreaRegistration.RegisterAllAreas(); 6             FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 7             RouteConfig.RegisterRoutes(RouteTable.Routes); 8             BundleConfig.RegisterBundles(BundleTable.Bundles); 9 10             WCFClientConfigurationManagement.Register();11         }12  }
View Code
1 
2
3
4
5
6
7
8
11
12
13
View Code

4.定义适合自己的WCF ClientBase

1 public class WCFClient 2 { 3         public static TResult ClientInvoke
(Func
functionInvoke) 4 { 5 string _ServiceName = typeof(TChannel).Name; 6 Binding binding = WCFClientConfigurationManagement.CreateBinding(_ServiceName); 7 EndpointAddress address = WCFClientConfigurationManagement.CreateAddress(_ServiceName); 8 TChannel _channel = ChannelFactory
.CreateChannel(binding, address); 9 TResult _Result = functionInvoke.Invoke(_channel);10 return _Result;11 }12 }
View Code

 

以上交代完毕,当然提醒初步了解WCF的人IPAddress 配置也可以写*.svc地址,可以在自寄宿在Windows Service 里,也可以是IIS宿主环境。写到这里,希望这篇随笔能帮助到需要帮助的人,这也就是它的价值所在了。

 

转载于:https://www.cnblogs.com/blakebook/p/5380097.html

你可能感兴趣的文章
JAVA数组的定义及用法
查看>>
18寒假第七测
查看>>
帧中继
查看>>
105:MyBatis常见实用面试题整理
查看>>
Base on QC Automation Framework v1.0
查看>>
bzoj 3261: 最大异或和 (可持久化trie树)
查看>>
UVA 11440 Help Tomisu
查看>>
bzoj千题计划258:bzoj3123: [Sdoi2013]森林
查看>>
开博@纪念
查看>>
linux的正则表达式
查看>>
Android 中EditText 与Keyboard 引起的UI bug
查看>>
20162316刘诚昊 2016-2017-2《程序设计与数据结构》课程总结
查看>>
代理模式---动态代理之JDK
查看>>
POJ 1182 食物链
查看>>
python xml解析和生成
查看>>
MySQL MGR集群搭建
查看>>
吴恩达深度学习笔记 cousrse4 week1作业
查看>>
程序员前辈走过的路
查看>>
hduoj 2062Subset sequence
查看>>
UBUNTU 10.04 更新源 补充
查看>>