Partager via


Extension de l’hébergement à l’aide de ServiceHostFactory

L’API standard ServiceHost pour l’hébergement de services dans Windows Communication Foundation (WCF) est un point d’extensibilité dans l’architecture WCF. Les utilisateurs peuvent dériver leurs propres classes hôtes de ServiceHost, généralement pour remplacer OnOpening() et utiliser ServiceDescription afin d'ajouter impérativement des points de terminaison par défaut ou pour modifier des comportements, avant d'ouvrir le service.

Dans l’environnement auto-hébergé, vous n’avez pas besoin de créer une instance personnalisée ServiceHost parce que vous écrivez le code qui instancie l’hôte, puis appelez Open() sur celui-ci après l'avoir instancié. Entre ces deux étapes, vous pouvez faire ce que vous voulez. Vous pouvez, par exemple, ajouter un nouveau IServiceBehavior:

public static void Main()  
{  
   ServiceHost host = new ServiceHost( typeof( MyService ) );  
   host.Description.Add( new MyServiceBehavior() );  
   host.Open();  
  
   ...  
}  

Cette approche n’est pas réutilisable. Le code qui manipule la description est codé dans le programme hôte (dans ce cas, la fonction Main(), il est donc difficile de réutiliser cette logique dans d’autres contextes. Il existe également d'autres façons d'ajouter un IServiceBehavior qui ne nécessitent pas de code impératif. Vous pouvez dériver un attribut à partir de ServiceBehaviorAttribute et le placer sur votre type d'implémentation de service, ou vous pouvez rendre un comportement personnalisé configurable et le composer dynamiquement en utilisant la configuration.

Toutefois, une légère variante de l’exemple peut également être utilisée pour résoudre ce problème. Une approche consiste à déplacer le code qui ajoute le ServiceBehavior hors de Main() et dans la méthode OnOpening d’un dérivé personnalisé de ServiceHost:

public class DerivedHost : ServiceHost  
{  
   public DerivedHost( Type t, params Uri baseAddresses ) :  
      base( t, baseAddresses ) {}  
  
   public override void OnOpening()  
   {  
  this.Description.Add( new MyServiceBehavior() );  
   }  
}  

Ensuite, à l’intérieur de Main() vous pouvez utiliser :

public static void Main()  
{  
   ServiceHost host = new DerivedHost( typeof( MyService ) );  
   host.Open();  
  
   ...  
}  

Vous avez maintenant encapsulé la logique personnalisée dans une abstraction propre qui peut être facilement réutilisée sur de nombreux exécutables hôtes différents.

Il n'est pas immédiatement évident comment utiliser cet élément personnalisé ServiceHost depuis l'intérieur des Internet Information Services (IIS) ou du service d'activation de processus Windows (WAS). Ces environnements sont différents de l’environnement auto-hôte, car l’environnement d’hébergement est celui instanciant le ServiceHost compte de l’application. L’infrastructure d’hébergement IIS et WAS ne connaît rien de votre dérivé personnalisé ServiceHost .

Le ServiceHostFactory a été conçu pour résoudre ce problème d'accès à votre ServiceHost personnalisé depuis l'intérieur d'IIS ou WAS. Étant donné qu’un hôte personnalisé dérivé de ServiceHost est configuré dynamiquement et peut potentiellement être de différents types, l’environnement d’hébergement ne le crée jamais directement. Au lieu de cela, WCF utilise un modèle de fabrique pour fournir une couche d’indirection entre l’environnement d’hébergement et le type concret du service. Sauf indication contraire, elle utilise une implémentation par défaut de ServiceHostFactory celle-ci retourne une instance de ServiceHost. Vous pouvez toutefois également fournir votre propre fabrique qui retourne votre hôte dérivé en spécifiant le nom de type CLR de l’implémentation de votre fabrique dans la directive @ServiceHost.

Le but est que pour les cas de base, l'implémentation de votre propre fabrique soit un exercice simple. Par exemple, voici un personnalisé ServiceHostFactory qui retourne un dérivé ServiceHost:

public class DerivedFactory : ServiceHostFactory  
{  
   public override ServiceHost CreateServiceHost( Type t, Uri[] baseAddresses )  
   {  
      return new DerivedHost( t, baseAddresses )  
   }  
}  

Pour utiliser cette fabrique au lieu de la fabrique par défaut, indiquez le nom de type dans la @ServiceHost directive comme suit :

<% @ServiceHost Factory="DerivedFactory" Service="MyService" %>

Bien qu’il n’y ait aucune limite technique pour faire ce que vous souhaitez avec le ServiceHost que vous retournez depuis CreateServiceHost, nous vous suggérons de conserver vos implémentations de fabrique aussi simples que possible. Si vous avez beaucoup de logique personnalisée, il est préférable de placer cette logique à l’intérieur de votre hôte plutôt qu’à l’intérieur de la fabrique afin qu’elle puisse être réutilisable.

Il existe une couche supplémentaire à l’API d’hébergement qui doit être mentionnée ici. WCF a ServiceHostBase également et ServiceHostFactoryBase, à partir desquels ServiceHost et ServiceHostFactory dérivent respectivement. Ceux-ci existent pour des scénarios plus avancés où vous devez échanger de grandes parties du système de métadonnées avec vos propres créations personnalisées.