加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

WCF服务的批量寄宿

发布时间:2020-12-16 09:10:54 所属栏目:asp.Net 来源:网络整理
导读:如果采用自我寄宿的方式,我们需要为每个寄宿的服务创建ServiceHost对象。但是一个应用往往具有很多服务需要被发布,基于单个服务的ServiceHost的创建将会变成一个很繁琐的事情。如果我们能够采用某种机制来读取所有配置的服务,并自动为它们创建相应的Servi

如果采用自我寄宿的方式,我们需要为每个寄宿的服务创建ServiceHost对象。但是一个应用往往具有很多服务需要被发布,基于单个服务的ServiceHost的创建将会变成一个很繁琐的事情。如果我们能够采用某种机制来读取所有配置的服务,并自动为它们创建相应的ServiceHost对象,这无疑是一种理想的方式。[源代码从这里下载]

我想很多人想到了直接读取表示寄宿服务的<system.serviceModel>/<services>/<service>配置元素列表,通过其name配置属性得到表示服务的“类型”,并据此创建相应的ServiceHost对象。这种做法是不被推荐的,原因有二:

  • <service>配置元素的name属性并不是寄宿服务的类型全名,而是通过ServiceBehaviorAttribute特性对应的服务配置名称;
  • 即使我们不对服务的配置名称作显式设置,让该名称表示成服务类型全名,但是由于它并包含程序集名称,我们往往不得不加载所有可用的程序集。

我们可以将需要需要批量寄宿的服务类型定义在配置文件中。很多人喜欢直接采用<appSettings>作为自定义的配置,但是我个人是既不推荐这种做法的,我觉得自定义结构化的配置节是更好的选择。批量寄宿的服务类型就定义在具有如下结构的 <artech.batchingHosting>配置节下。

   1: <artech.batchingHosting>
   3:   ="Artech.BatchingHosting.BarService,1)">/>
    
   2: {
   4:     public ServiceTypeElementCollection ServiceTypes
   6:         get { return (ServiceTypeElementCollection)this[""]; }
   8:? 
  10:     {
  12:                     as BatchingHostingSettings;
  14: }
  16: {
  18:     {
  20:     }
  22:     {
  24:         return serviceTypeElement.ServiceType.MetadataToken;
  26: }
  28: {
  31:     public Type ServiceType
  33:         get { return (Type)"type"]; }
  35:     }
class AssemblyQualifiedTypeNameConverter : ConfigurationConverterBase
   4:     {
   6:         if (string.IsNullOrEmpty(typeName))
   8:             null;
  10:         Type result = Type.GetType(typeName,1)">false);
  12:         {
  14:         }
  16:     }
  19:         Type type = value as Type;
  21:         {
  23:         }
  26: }

真正的服务批量寄宿是通过具有如下定义的ServiceHostCollection来实现的。ServiceHostCollection本质上就是一个ServiceHost的集合,我们可以通过构造函数和自定义的Add方法为指定的一组服务类型创建ServiceHost。在构造函数中,我们通过加载BatchingHostingSettings配置节的方式获取需要批量寄宿的服务类型,并为之创建ServiceHost。

public ServiceHostCollection(params Type[] serviceTypes)
foreach (ServiceTypeElement element in settings.ServiceTypes)
  10:? 
  12:         { 
  15:     }
  17:     {
  19:         {
  21:         }
  23:     void Open()
  25:         foreach (ServiceHost host in this)
  27:             host.Open();
  29:     }
  31:     {
  33:         {
  35:         }
  37: }

定义在ServiceHostCollection中的Open方法实现了对所有ServiceHost对象的批量开启。ServiceHostCollection还实现了IDisposable接口,并在Dispose方法中实现了对ServiceHost的批量关闭。

现在我们定义了FooService、BarService和BazService三个服务类型,它们分别实现了契约接口IFoo、IBar和IBar。三个服务以及包含的终结点定义在如下的配置中,而三个服务类型同时被定义在了我们自定义的<artech.batchingHosting>配置节下。

3: section name="artech.batchingHosting"
   5:            Artech.BatchingHosting"   6:      7:   system.serviceModel   8:     services   9:       service ="Artech.BatchingHosting.FooService"  10:         endpoint address="http://127.0.0.1:3721/fooservice"
  12:                     contract="Artech.BatchingHosting.IFoo"  13:       service  14:       ="Artech.BatchingHosting.BarService"="http://127.0.0.1:3721/barservice"
  17:                     ="Artech.BatchingHosting.IBar"  18:         19:       ="Artech.BatchingHosting.BazService"="http://127.0.0.1:3721/bazservice"
using (ServiceHostCollection hosts = new ServiceHostCollection())
   5:         host.Opened += (sender,arg) => Console.WriteLine("服务{0}开始监听",
   8:     hosts.Open();
  10: }

上面这段代码执行之后,控制台上将会具有如下一段输出文字,这充分证明了我们对三个服务成功地进行了批量寄宿。