Erweitern des Hosting mit ServiceHostFactoryExtending Hosting Using ServiceHostFactory

Der Standard ServiceHost API zum Hosten von Diensten in Windows Communication Foundation (WCF) ist ein Erweiterungspunkt. er in der WCF-Architektur.The standard ServiceHost API for hosting services in Windows Communication Foundation (WCF) is an extensibility point in the WCF architecture. Benutzer können ihre eigenen Hostklassen von ServiceHost ableiten, üblicherweise um OnOpening() für die Verwendung von ServiceDescription zu überschreiben, um Endpunkte imperativ hinzuzufügen oder das Verhalten vor dem Öffnen des Diensts zu ändern.Users can derive their own host classes from ServiceHost, usually to override OnOpening() to use ServiceDescription to add default endpoints imperatively or modify behaviors, prior to opening the service.

In der selbst gehosteten Umgebung müssen Sie keine benutzerdefinierte ServiceHost-Klasse erstellen, weil Sie den Code schreiben, der den Host instantiiert, und rufen anschließend Open() für den Host auf.In the self-host environment, you do not have to create a custom ServiceHost because you write the code that instantiates the host and then call Open() on it after you instantiate it. Zwischen diesen beiden Schritten können Sie beliebige Vorgänge ausführen.Between those two steps you can do whatever you want. Sie könnten z. B. ein neues IServiceBehavior hinzufügen:You could, for example, add a new IServiceBehavior:

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

   ...  
}  

Dieser Ansatz ist nicht wiederverwendbar.This approach is not reusable. Der Code, der die Beschreibung bearbeitet, wird in das Hostprogramm eingefügt (in diesem Fall in die Main()-Funktion), daher ist es schwierig, diese Logik in anderen Kontexten wiederzuverwenden.The code that manipulates the description is coded into the host program (in this case, the Main() function), so it is difficult to reuse that logic in other contexts. Es gibt auch andere Wege, ein IServiceBehavior hinzuzufügen, die keinen imperativen Code erfordern.There are also other ways of adding an IServiceBehavior that do not require imperative code. Sie können von ServiceBehaviorAttribute ein Attribut ableiten und es in Ihren Dienstimplementierungstyp aufnehmen, oder Sie können ein benutzerdefiniertes Verhalten konfigurierbar gestalten und es dynamisch mithilfe einer Konfiguration erstellen.You can derive an attribute from ServiceBehaviorAttribute and put that on your service implementation type or you can make a custom behavior configurable and compose it dynamically using configuration.

Es kann jedoch auch eine kleine Variante des Beispiels verwendet werden, um dieses Problem zu lösen.However, a slight variation of the example can also be used to solve this problem. Ein Ansatz besteht darin, den Code, mit dem ServiceBehavior hinzugefügt wird, von Main() in die OnOpening-Methode einer benutzerdefinierten Ableitung von ServiceHost zu verschieben:One approach is to move the code that adds the ServiceBehavior out of Main() and into the OnOpening method of a custom derivative of ServiceHost:

public class DerivedHost : ServiceHost  
{  
   public DerivedHost( Type t, params Uri baseAddresses ) :  
      base( t, baseAddresses ) {}  

   public override void OnOpening()  
   {  
  this.Description.Add( new MyServiceBehavior() );  
   }  
}  

Dann können Sie innerhalb von Main() Folgendes verwenden.Then, inside of Main() you can use:

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

   ...  
}  

Sie haben jetzt die benutzerdefinierte Logik in einer abstrakten Form gekapselt, die so in verschiedenen Hostimplementierungen wiederverwendet werden kann.Now you have encapsulated the custom logic into a clean abstraction that can be easily reused across many different host executables.

Es ist nicht unmittelbar einsichtig, wie diese benutzerdefinierte ServiceHost-Klasse innerhalb von IIS (Internetinformationsdiensten) oder WAS (Windows Process Activation Service) verwendet werden kann.It is not immediately obvious how to use this custom ServiceHost from inside of Internet Information Services (IIS) or Windows Process Activation Service (WAS). Diese Umgebungen unterscheiden sich von einer selbst gehosteten Umgebung, weil die Hostumgebung im Namen der Anwendung ServiceHost instantiiert.Those environments are different than the self-host environment, because the hosting environment is the one instantiating the ServiceHost on behalf of the application. Die Hostumgebungen IIS und WAS wissen jedoch nichts von Ihrer benutzerdefinierten ServiceHost-Ableitung.The IIS and WAS hosting infrastructure does not know anything about your custom ServiceHost derivative.

ServiceHostFactory wurde dafür konzipiert, dieses Problem des Zugriffs auf Ihre benutzerdefinierte ServiceHost-Klasse durch IIS oder WAS zu lösen.The ServiceHostFactory was designed to solve this problem of accessing your custom ServiceHost from within IIS or WAS. Da ein benutzerdefinierter, von ServiceHost abgeleiteter Host dynamisch konfiguriert und von potentiell unterschiedlichem Typ ist, wird er von der Hostumgebung niemals direkt instantiiert.Because a custom host that is derived from ServiceHost is dynamically configured and potentially of various types, the hosting environment never instantiates it directly. Stattdessen verwendet WCF ein Factorymuster, um eine Dereferenzierungsschicht zwischen der hostumgebung und dem konkreten Typ des Diensts bereitzustellen.Instead, WCF uses a factory pattern to provide a layer of indirection between the hosting environment and the concrete type of the service. Sofern Sie nichts anderes angeben, wird dazu eine Standardimplementierung von ServiceHostFactory verwendet, die eine Instanz von ServiceHost zurückgibt.Unless you tell it otherwise, it uses a default implementation of ServiceHostFactory that returns an instance of ServiceHost. Aber Sie können auch angeben, eine eigene Factory, die den abgeleiteten Host zurückgibt, durch Angeben der CLR-Typnamen Ihrer Factory-Implementierung in der @ServiceHost Richtlinie.But you can also provide your own factory that returns your derived host by specifying the CLR type name of your factory implementation in the @ServiceHost directive.

Ziel ist, dass in den grundlegenden Fällen die Implementierung einer eigenen Factory eine einfache Angelegenheit sein sollte.The intent is that for basic cases, implementing your own factory should be a straight forward exercise. Als Beispiel folgt hier eine benutzerdefinierte ServiceHostFactory, die eine abgeleitete ServiceHost-Klasse zurückgibt:For example, here is a custom ServiceHostFactory that returns a derived ServiceHost:

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

Um diese Factory statt der standardfactory verwenden möchten, geben Sie den Typnamen in der @ServiceHost Richtlinie wie folgt:To use this factory instead of the default factory, provide the type name in the @ServiceHost directive as follows:

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

Zwar gibt es keine technische Grenze für das, was Sie mit einer von ServiceHost zurückgegebenen CreateServiceHost-Klasse tun können, jedoch wird empfohlen, die Implementierung der Factory so einfach wie möglich zu halten.While there is no technical limit on doing what you want to the ServiceHost you return from CreateServiceHost, we suggest that you keep your factory implementations as simple as possible. Falls Sie benutzerdefinierte Logik großen Umfangs definieren müssen, platzieren Sie sie statt in die Factory besser in den Host, damit der Code einfacher wiederverwendet werden kann.If you have lots of custom logic, it is better to put that logic inside of you host instead of inside the factory so that it can be reusable.

Es gibt noch eine weitere Ebene der Host-API, die hier erwähnt werden muss.There is one more layer to the hosting API that should be mentioned here. WCF verfügt auch über ServiceHostBase und ServiceHostFactoryBase, von dem ServiceHost und ServiceHostFactory abgeleitet.WCF also has ServiceHostBase and ServiceHostFactoryBase, from which ServiceHost and ServiceHostFactory respectively derive. Diese sind für erweiterte Szenarien vorgesehen, in denen Sie große Teile des Metadatensystems mit Ihren benutzerdefinierten Klassen auslagern müssen.Those exist for more advanced scenarios where you must swap out large parts of the metadata system with your own customized creations.