WCF服务的批量寄宿

发表于:2012-02-09来源:博客园作者:Artech点击数: 标签:WCF
如果采用自我寄宿的方式,我们需要为每个寄宿的服务创建ServiceHost对象。但是一个应用往往具有很多服务需要被发布,基于单个服务的ServiceHost的创建将会变成一个很繁琐的

  如果采用自我寄宿的方式,我们需要为每个寄宿的服务创建ServiceHost对象。但是一个应用往往具有很多服务需要被发布,基于单个服务的ServiceHost的创建将会变成一个很繁琐的事情。如果我们能够采用某种机制来读取所有配置的服务,并自动为它们创建相应的ServiceHost对象,这无疑是一种理想的方式。
  我想很多人想到了直接读取表示寄宿服务的//配置元素列表,通过其name配置属性得到表示服务的“类型”,并据此创建相应的ServiceHost对象。这种做法是不被推荐的,原因有二:

  配置元素的name属性并不是寄宿服务的类型全名,而是通过ServiceBehaviorAttribute特性对应的服务配置名称;

  即使我们不对服务的配置名称作显式设置,让该名称表示成服务类型全名,但是由于它并包含程序集名称,我们往往不得不加载所有可用的程序集。

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

  1:

  2:

  3:

  4:

  5:

  上面XML表示的自定义配置节通过具有如下定义的BatchingHostingSettings表示。BatchingHostingSettings包含一个通过ServiceTypeElementCollection表示的配置元素集合,而具体的配置元素类型为ServiceTypeElement。而ServiceTypeElement的配置ServiceType表示具体的服务类型。

  1: public class BatchingHostingSettings: ConfigurationSection

  2: {

  3: [ConfigurationProperty("", IsDefaultCollection = true)]

  4: public ServiceTypeElementCollection ServiceTypes

  5: {

  6: get { return (ServiceTypeElementCollection)this[""]; }

  7: }

  8:

  9: public static BatchingHostingSettings GetSection()

  10: {

  11: return ConfigurationManager.GetSection("artech.batchingHosting")

  12: as BatchingHostingSettings;

  13: }

  14: }

  15: public class ServiceTypeElementCollection : ConfigurationElementCollection

  16: {

  17: protected override ConfigurationElement CreateNewElement()

  18: {

  19: return new ServiceTypeElement();

  20: }

  21: protected override object GetElementKey(ConfigurationElement element)

  22: {

  23: ServiceTypeElement serviceTypeElement = (ServiceTypeElement)element;

  24: return serviceTypeElement.ServiceType.MetadataToken;

  25: }

  26: }

  27: public class ServiceTypeElement : ConfigurationElement

  28: {

  29: [ConfigurationProperty("type",IsRequired = true)]

  30: [TypeConverter(typeof(AssemblyQualifiedTypeNameConverter))]

  31: public Type ServiceType

  32: {

  33: get { return (Type)this["type"]; }

  34: set { this["type"] = value; }

  35: }

  36: }

  ServiceTypeElement的ServiceType属性上应用了一个TypeConverterAttribute特性并将类型转换器类型设置为AssemblyQualifiedTypeNameConverter,这是为了让配置系统能够自动实现以字符串表示的配置属性值与Type对象之间的转换。这个类型转换器是我们自定义的,具体定义如下:

  1: public class AssemblyQualifiedTypeNameConverter : ConfigurationConverterBase

  2: {

  3: public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)

  4: {

  5: string typeName = (string)value;

  6: if (string.IsNullOrEmpty(typeName))

  7: {

  8: return null;

  9: }

  10: Type result = Type.GetType(typeName, false);

  11: if (result == null)

  12: {

  13: throw new ArgumentException(string.Format("不能加载类型\"{0}\"", typeName));

  14: }

  15: return result;

  16: }

  17: public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)

  18: {

  19: Type type = value as Type;

  20: if (null == type)

  21: {

  22: throw new ArgumentNullException("value");

  23: }

  24: return type.AssemblyQualifiedName;

  25: }

  26: }

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

  1: public class ServiceHostCollection : Collection, IDisposable

  2: {

  3: public ServiceHostCollection(params Type[] serviceTypes)

  4: {

  5: BatchingHostingSettings settings = BatchingHostingSettings.GetSection();

原文转自:http://www.ltesting.net