Extension de l'hébergement à l'aide de ServiceHostFactory
L'API ServiceHost standard pour les services d'hébergement dans Windows Communication Foundation (WCF) est un point d'extensibilité dans l'architecture WCF. Les utilisateurs peuvent dériver leurs propres classes d'hôte de ServiceHost, habituellement pour substituer OnOpening et utiliser ServiceDescription afin d'ajouter des points de terminaison par défaut de façon impérative ou modifier des comportements, avant d'ouvrir le service.
Dans l'environnement auto-hébergé, vous ne devez pas créer un ServiceHost personnalisé parce que vous écrivez le code qui instancie l'hôte puis appelle Open après l'avoir instancié. Entre ces deux étapes, vous pouvez faire ce que vous souhaitiez. Par exemple, vous pouvez 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 y a également d'autres façons d'ajouter un IServiceBehavior qui ne requiert pas de code impératif. Vous pouvez dériver un attribut de ServiceBehaviorAttribute et mettre cela sur le type d'implémentation de votre service ou vous pouvez créer un comportement personnalisé configurable et le composer dynamiquement à l'aide de la configuration.
Toutefois, le problème peut également être résolu en modifiant légèrement l'exemple. Une approche possible consiste à déplacer le code qui ajoute ServiceBehavior hors de Main()
et le placer dans la méthode OnOpening d'une dérivée personnalisée 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() );
}
}
Dans Main()
, vous pouvez ensuite utiliser :
public static void Main()
{
ServiceHost host = new DerivedHost( typeof( MyService ) );
host.Open();
...
}
Vous avez ainsi encapsulé la logique personnalisée dans une abstraction vierge qui peut être facilement réutilisée dans de nombreux exécutables d'hôte différents.
Il n'est pas évident de savoir comment utiliser cette version ServiceHost personnalisée dans IIS (Internet Information Services) ou dans le service d'activation de processus de Windows (WAS). Ces environnements sont différents de l'environnement auto-hébergé, car l'environnement d'hébergement est celui qui instancie le ServiceHost pour le compte de l'application. L'infrastructure d'hébergement IIS et WAS ne connaît rien de votre dérivée ServiceHost personnalisée.
ServiceHostFactory a été conçu pour résoudre ce problème d'accès à votre ServiceHost personnalisé dans IIS ou WAS. Parce qu'un hôte personnalisé dérivé de ServiceHost est configuré dynamiquement et appartient potentiellement à des types différents, l'environnement d'hébergement ne l'instancie 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. À moins que vous lui indiquiez d'agir autrement, il utilise une implémentation par défaut de ServiceHostFactory qui retourne une instance de ServiceHost. Vous pouvez également fournir votre propre fabrique renvoyant votre hôte dérivé, en spécifiant le nom de type CLR correspondant à 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 ServiceHostFactory personnalisé qui retourne un ServiceHostdérivé :
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, fournissez le nom de type dans la directive @ServiceHost comme suit :
<% @ServiceHost Factory=”DerivedFactory” Service=”MyService” %>
Bien qu'il n'y ait aucune limitation technique en ce qui concerne ce que vous pouvez faire au niveau du ServiceHost que vous avez retourné de CreateServiceHost, nous vous suggérons de garder vos implémentations de fabrique aussi simples que possible. Si vous avez beaucoup de logique personnalisée, il est préférable de la placer dans votre hôte plutôt que dans la fabrique, afin de pouvoir la réutiliser.
Une couche supplémentaire de l'API d'hébergement doit être mentionnée ici. WCF a également ServiceHostBase et ServiceHostFactoryBase, desquels ServiceHost et ServiceHostFactory dérivent respectivement. Ceux-ci sont prévus pour des scénarios plus avancés où vous devez permuter des parties importantes du système de métadonnées avec vos propres créations personnalisées.