Utöka värdtjänster med hjälp av ServiceHostFactory
Standard-API ServiceHost :et för värdtjänster i Windows Communication Foundation (WCF) är en utökningspunkt i WCF-arkitekturen. Användare kan härleda sina egna värdklasser från ServiceHost, vanligtvis för att åsidosätta OnOpening() för att lägga ServiceDescription till standardslutpunkter imperativt eller ändra beteenden innan de öppnar tjänsten.
I självvärdmiljön behöver du inte skapa en anpassad ServiceHost eftersom du skriver koden som instansierar värden och sedan anropar Open() den när du har instansierat den. Mellan dessa två steg kan du göra vad du vill. Du kan till exempel lägga till en ny IServiceBehavior:
public static void Main()
{
ServiceHost host = new ServiceHost( typeof( MyService ) );
host.Description.Add( new MyServiceBehavior() );
host.Open();
...
}
Den här metoden kan inte återanvändas. Koden som ändrar beskrivningen kodas i värdprogrammet (i det här fallet funktionen Main(), så det är svårt att återanvända den logiken i andra sammanhang. Det finns också andra sätt att lägga till en IServiceBehavior som inte kräver imperativ kod. Du kan härleda ett attribut från ServiceBehaviorAttribute och placera det på din tjänstimplementeringstyp eller så kan du göra ett anpassat beteende konfigurerbart och skriva det dynamiskt med hjälp av konfigurationen.
En liten variant av exemplet kan dock också användas för att lösa det här problemet. En metod är att flytta koden som lägger till ServiceBehavior från Main()
och till OnOpening metoden för ett anpassat derivat av ServiceHost:
public class DerivedHost : ServiceHost
{
public DerivedHost( Type t, params Uri baseAddresses ) :
base( t, baseAddresses ) {}
public override void OnOpening()
{
this.Description.Add( new MyServiceBehavior() );
}
}
Sedan kan du använda:Main()
public static void Main()
{
ServiceHost host = new DerivedHost( typeof( MyService ) );
host.Open();
...
}
Nu har du kapslat in den anpassade logiken i en ren abstraktion som enkelt kan återanvändas i många olika körbara värden.
Det är inte omedelbart uppenbart hur du använder den här anpassade ServiceHost inifrån Internet Information Services (IIS) eller Windows Process Activation Service (WAS). Dessa miljöer skiljer sig från självvärdmiljön eftersom värdmiljön är den som instansierar ServiceHost för programmets räkning. IIS- och WAS-värdinfrastrukturen vet ingenting om ditt anpassade ServiceHost derivat.
ServiceHostFactory Har utformats för att lösa det här problemet med att komma åt din anpassade ServiceHost inifrån IIS eller WAS. Eftersom en anpassad värd som härleds från ServiceHost är dynamiskt konfigurerad och potentiellt av olika typer, instansierar värdmiljön den aldrig direkt. I stället använder WCF ett fabriksmönster för att tillhandahålla ett lager av indirektion mellan värdmiljön och den konkreta typen av tjänst. Om du inte anger något annat använder den en standardimplementering av ServiceHostFactory som returnerar en instans av ServiceHost. Men du kan också ange en egen fabrik som returnerar den härledda värden genom att ange CLR-typnamnet för fabriksimplementeringen i @ServiceHost direktivet.
Avsikten är att implementeringen av din egen fabrik i grundläggande fall ska vara en enkel övning. Här är till exempel en anpassad ServiceHostFactory som returnerar en härledd ServiceHost:
public class DerivedFactory : ServiceHostFactory
{
public override ServiceHost CreateServiceHost( Type t, Uri[] baseAddresses )
{
return new DerivedHost( t, baseAddresses )
}
}
Om du vill använda den här fabriken i stället för standardfabriken anger du typnamnet i @ServiceHost direktivet på följande sätt:
<% @ServiceHost Factory="DerivedFactory" Service="MyService" %>
Även om det inte finns någon teknisk gräns för att göra vad du vill att ServiceHost du ska returnera från CreateServiceHost, föreslår vi att du håller dina fabriksimplementeringar så enkla som möjligt. Om du har massor av anpassad logik är det bättre att placera den logiken i värden i stället för inuti fabriken så att den kan återanvändas.
Det finns ytterligare ett lager i värd-API:et som bör nämnas här. WCF har ServiceHostBase också och ServiceHostFactoryBase, som ServiceHost respektive ServiceHostFactory härleds från. De finns för mer avancerade scenarier där du måste växla ut stora delar av metadatasystemet med dina egna anpassade skapelser.