Windows Communication Foundation(WCF)中托管服务的标准 ServiceHost API 是 WCF 体系结构中的扩展点。 在打开服务之前,用户可以从 ServiceHost 派生各自的宿主类,通常是重写 OnOpening() 以使用 ServiceDescription 来以强制方式添加默认终结点或修改行为。
在自承载环境中,无需创建自定义 ServiceHost ,因为你编写了实例化主机的代码,然后在实例化主机后对其进行调用 Open() 。 在这两个步骤之间,你可以做任何你想做的事情。 例如,可以添加新的 IServiceBehavior:
public static void Main()
{
ServiceHost host = new ServiceHost( typeof( MyService ) );
host.Description.Add( new MyServiceBehavior() );
host.Open();
...
}
此方法不可重用。 作说明的代码将编码到主机程序(在本例中为 Main()函数中,因此很难在其他上下文中重复使用该逻辑。 还有其他不需要命令性代码的方法来添加IServiceBehavior。 可以从ServiceBehaviorAttribute派生一个属性并将其应用于服务实现类型,也可以使自定义行为可配置并动态地通过配置进行组合。
但是,该示例的细微变化也可用于解决此问题。 一个办法是将添加 ServiceBehavior 的代码从 Main()
中移动到 OnOpening 的自定义派生的 ServiceHost 方法中:
public class DerivedHost : ServiceHost
{
public DerivedHost( Type t, params Uri baseAddresses ) :
base( t, baseAddresses ) {}
public override void OnOpening()
{
this.Description.Add( new MyServiceBehavior() );
}
}
然后,您可以在Main()
的内部使用以下内容:
public static void Main()
{
ServiceHost host = new DerivedHost( typeof( MyService ) );
host.Open();
...
}
现在,你已将自定义逻辑封装到一个干净的抽象中,可以在许多不同的主机可执行文件中轻松重复使用。
目前还不清楚如何从 Internet Information Services(IIS)或 Windows 进程激活服务(WAS)内部使用此自定义 ServiceHost 。 这些环境不同于自托管环境,因为宿主环境是代表应用程序实例化 ServiceHost 的。 IIS 和 WAS 托管基础结构并不了解您的自定义 ServiceHost 派生。
ServiceHostFactory 旨在解决从 IIS 或 WAS 中访问自定义 ServiceHost 的问题。 由于派生自 ServiceHost 的自定义主机是动态配置的,并且可能有多种类型,因此宿主环境永远不会直接实例化它。 相反,WCF 使用工厂模式在托管环境和服务的具体类型之间提供间接层。 除非另有说明,否则它会使用ServiceHostFactory的默认实现,该实现返回ServiceHost的实例。 但是,也可以通过在 @ServiceHost 指令中指定工厂实现的 CLR 类型名称来提供自己的返回派生宿主的工厂。
对于简单的情形,实现您自己的工厂的练习应该是简单明了的。 例如,下面是用于返回派生的 ServiceHostFactory 的自定义 ServiceHost:
public class DerivedFactory : ServiceHostFactory
{
public override ServiceHost CreateServiceHost( Type t, Uri[] baseAddresses )
{
return new DerivedHost( t, baseAddresses )
}
}
若要使用此工厂而不是默认工厂,请在指令中 @ServiceHost 提供类型名称,如下所示:
<% @ServiceHost Factory="DerivedFactory" Service="MyService" %>
尽管对于从 ServiceHost 返回的 CreateServiceHost 可以执行什么操作没有技术限制,但建议您尽可能使工厂实现简单化。 如果你有大量的自定义逻辑,最好将该逻辑放在主机内部而不是工厂内部,以便可以重复使用。
托管 API 还有一个层,应该在此处提及。 WCF 还具有ServiceHostBase和ServiceHostFactoryBase,从中分别派生出ServiceHost和ServiceHostFactory。 这些是针对更高级的场景存在的,在这些场景中,你必须用自己的定制设计来替换掉大部分的元数据系统。