Udostępnij przez


Rozszerzanie hostingu przy użyciu 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ą tworzyć własne klasy hostów z ServiceHost, zazwyczaj aby zastąpić OnOpening() i przy pomocy ServiceDescription imperatywnie dodawać domyślne punkty końcowe lub modyfikować zachowanie, przed uruchomieniem 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() na nim 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 nadaje się do ponownego użycia. 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 wyprowadzić atrybut z ServiceBehaviorAttribute i umieścić go w typie implementacji usługi, lub skonfigurować niestandardowe zachowanie, aby można było je dynamicznie komponować za pomocą 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 ServiceBehavior z Main() do metody OnOpening 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() );  
   }  
}  

Następnie, wewnątrz Main(), możesz użyć:

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

Teraz zhermetyzowano logikę niestandardową w czystą abstrakcję, którą można łatwo użyć w wielu różnych programach 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 samodzielnego hostowania, ponieważ środowisko hostingu jest tym, które tworzy wystąpienie ServiceHost w imieniu aplikacji. Infrastruktura hostingu usług IIS i WAS nie ma żadnych informacji o Twoim niestandardowym rozszerzeniu ServiceHost.

ServiceHostFactory został zaprojektowany, aby rozwiązać problem z uzyskiwaniem dostępu do niestandardowego ServiceHost z poziomu usług IIS lub WAS. Ponieważ niestandardowy host wywodzący się z ServiceHost jest konfigurowany dynamicznie i może mieć różne typy, środowisko hostingu nigdy nie tworzy go bezpośrednio. Zamiast tego WCF używa wzorca fabryki do zapewnienia warstwy pośredniej między środowiskiem hostującym a konkretnym typem usługi. Jeśli nie określisz inaczej, zostanie użyta domyślna implementacja ServiceHostFactory, która zwraca wystąpienie ServiceHost. Możesz także podać własną fabrykę, która zwraca hosta pochodnego, podając nazwę typu CLR implementacji fabryki w dyrektywie @ServiceHost.

Celem jest, aby w podstawowych przypadkach implementacja własnej fabryki była prostym ćwiczeniem. Na przykład, oto niestandardowy ServiceHostFactory, który zwraca pochodny ServiceHost.

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 następujący sposób: @ServiceHost

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

Chociaż nie ma żadnego limitu technicznego na modyfikowanie ServiceHost zwracanego z CreateServiceHost, sugerujemy, aby implementacje fabryki były jak najprostsze. Jeśli masz wiele niestandardowej logiki, lepiej jest umieścić tę logikę wewnątrz hosta zamiast wewnątrz fabryki, aby można było ją ponownie używać.

Istnieje jeszcze jedna warstwa interfejsu API hostingu, o której należy wspomnieć tutaj. WCF ma również ServiceHostBase i ServiceHostFactoryBase, z których odpowiednio pochodzą ServiceHost i ServiceHostFactory. 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.