Rozszerzanie hostingu za pomocą elementu ServiceHostFactory

Standardowy ServiceHost interfejs API do hostowania usług w programie Windows Communication Foundation (WCF) to punkt rozszerzalności w architekturze WCF. Użytkownicy mogą uzyskiwać własne klasy hostów z ServiceHostklasy , zwykle do zastąpienia OnOpening() , aby użyć ServiceDescription polecenia w celu imperatywnego dodawania domyślnych punktów końcowych lub modyfikowania zachowań przed otwarciem usługi.

W środowisku self-host nie trzeba tworzyć niestandardowego ServiceHost , ponieważ piszesz kod, który tworzy wystąpienie hosta, a następnie wywołuje Open() go po utworzeniu wystąpienia. Między tymi dwoma krokami możesz wykonać dowolną czynność. Możesz na przykład dodać nowy IServiceBehaviorelement :

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

Takie podejście nie jest wielokrotnego użytku. Kod, który manipuluje opisem, jest kodowany w programie hosta (w tym przypadku funkcji Main(), więc trudno jest użyć tej logiki w innych kontekstach. Istnieją również inne sposoby dodawania elementu IServiceBehavior , które nie wymagają kodu imperatywnego. Możesz uzyskać atrybut i ServiceBehaviorAttribute umieścić go na typie implementacji usługi lub skonfigurować niestandardowe zachowanie i utworzyć go dynamicznie przy użyciu konfiguracji.

Jednak niewielkie różnice w przykładzie mogą być również używane do rozwiązania tego problemu. Jednym z podejść jest przeniesienie kodu, który dodaje element ServiceBehavior z Main() i do OnOpening metody niestandardowego pochodnego elementu 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() Następnie wewnątrz możesz użyć:

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

Teraz za hermetyzowano logikę niestandardową w czystą abstrakcję, którą można łatwo użyć w wielu różnych plikach wykonywalnych hosta.

Nie jest od razu oczywiste, jak używać tego niestandardowego ServiceHost z poziomu usług Internet Information Services (IIS) lub usługi aktywacji procesów systemu Windows (WAS). Te środowiska różnią się od środowiska hosta własnego, ponieważ środowisko hostingu tworzy wystąpienie ServiceHost w imieniu aplikacji. Infrastruktura hostingu usług IIS i WAS nie wie nic o niestandardowym pochodnym ServiceHost .

Został ServiceHostFactory zaprojektowany w celu rozwiązania tego problemu z uzyskiwaniem dostępu do niestandardowego ServiceHost z poziomu usług IIS lub WAS. Ponieważ niestandardowy host, z którego pochodzi ServiceHost , jest konfigurowany dynamicznie i potencjalnie różnych typów, środowisko hostingu nigdy nie tworzy wystąpienia bezpośrednio. Zamiast tego program WCF używa wzorca fabryki do zapewnienia warstwy pośredniej między środowiskiem hostingu a konkretnym typem usługi. Jeśli nie zostanie to poinformowane inaczej, zostanie użyta domyślna implementacja ServiceHostFactory , która zwraca wystąpienie ServiceHostklasy . Możesz jednak również udostępnić własną fabrykę, która zwraca hosta pochodnego, określając nazwę typu CLR implementacji fabryki w @ServiceHost dyrektywie.

Celem jest to, że w przypadku podstawowych przypadków implementacja własnej fabryki powinna być prostym ćwiczeniem. Na przykład poniżej znajduje się niestandardowy obiekt ServiceHostFactory , który zwraca pochodne ServiceHostpolecenie :

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

Aby użyć tej fabryki zamiast domyślnej fabryki, podaj nazwę typu w dyrektywie w @ServiceHost następujący sposób:

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

Chociaż nie ma żadnego limitu technicznego dotyczącego wykonywania tego, co chcesz ServiceHost zwrócić z CreateServiceHost, sugerujemy, że implementacje fabryki są jak najprostsze. Jeśli masz wiele niestandardowych logiki, lepiej jest umieścić tę logikę wewnątrz hosta zamiast wewnątrz fabryki, aby można było go ponownie używać.

Istnieje jeszcze jedna warstwa interfejsu API hostingu, o której należy wspomnieć tutaj. WCF ma ServiceHostBase również wartości i ServiceHostFactoryBase, z których ServiceHostFactoryServiceHost i pochodzą odpowiednio. Istnieją one w bardziej zaawansowanych scenariuszach, w których należy zamienić duże części systemu metadanych przy użyciu własnych dostosowanych kreacji.