WCF(Windows Communication Foundation)에서 서비스를 호스팅하기 위한 표준 ServiceHost API는 WCF 아키텍처의 확장성 지점입니다. 사용자는 일반적으로 서비스 열기 전에 기본 엔드포인트를 명령적으로 추가하거나 동작을 수정하기 위해 ServiceHost를 재정의하여 OnOpening()에서 자체 호스트 클래스를 파생시킬 수 있습니다.
자체 호스트 환경에서는 호스트를 인스턴스화하고 그 후에 ServiceHost을 호출하는 코드를 작성하기 때문에 사용자 지정 Open()을 만들 필요가 없습니다. 이 두 단계 사이에는 원하는 대로 수행할 수 있습니다. 예를 들어 다음과 같이 새 IServiceBehavior항목을 추가할 수 있습니다.
public static void Main()
{
ServiceHost host = new ServiceHost( typeof( MyService ) );
host.Description.Add( new MyServiceBehavior() );
host.Open();
...
}
이 방법은 재사용할 수 없습니다. 설명을 조작하는 코드는 호스트 프로그램(이 경우 Main() 함수)으로 코딩되므로 다른 컨텍스트에서 해당 논리를 다시 사용하는 것은 어렵습니다. IServiceBehavior를 추가하는 것은 명령적 코드가 필요하지 않은 다른 방법들도 있습니다. 특성을 ServiceBehaviorAttribute에서 유도하여 이를 서비스 구현 유형에 적용하거나, 사용자 정의 동작을 구성 가능하게 만들어 구성을 통해 동적으로 조합할 수 있습니다.
그러나 예제의 약간의 변형을 사용하여 이 문제를 해결할 수도 있습니다. 한 가지 방법은 ServiceBehavior를 추가하는 코드를 Main()
에서 사용자 지정 파생 개체OnOpening의 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()
안에서 다음을 사용할 수 있습니다.
public static void Main()
{
ServiceHost host = new DerivedHost( typeof( MyService ) );
host.Open();
...
}
이제 사용자 지정 논리를 여러 호스트 실행 파일에서 쉽게 재사용할 수 있는 정리된 추상화로 캡슐화했습니다.
IIS(인터넷 정보 서비스) 또는 WAS(Windows Process Activation Service) 내부에서 이 사용자 지정 ServiceHost 을 사용하는 방법은 즉시 명확하지 않습니다. 호스팅 환경은 애플리케이션을 대신하여 인스턴스화하는 ServiceHost 환경이므로 이러한 환경은 자체 호스트 환경과 다릅니다. IIS 및 WAS 호스팅 인프라는 사용자 지정 ServiceHost 파생 항목에 대해 아무것도 알지 못합니다.
IIS ServiceHostFactory 또는 WAS 내에서 사용자 지정 ServiceHost 에 액세스하는 이 문제를 해결하도록 설계되었습니다. 파생된 ServiceHost 사용자 지정 호스트는 동적으로 구성되고 잠재적으로 다양한 형식이므로 호스팅 환경에서 직접 인스턴스화하지 않습니다. 대신 WCF는 팩터리 패턴을 사용하여 호스팅 환경과 서비스의 구체적인 형식 간에 간접 참조 계층을 제공합니다. 별도로 지정하지 않으면 ServiceHostFactory의 인스턴스를 반환하는 기본 구현인 ServiceHost를 사용합니다. 그러나 지시문에서 팩터리 구현의 CLR 형식 이름을 지정하여 파생된 호스트를 반환하는 고유한 팩터리를 @ServiceHost 제공할 수도 있습니다.
기본 사례의 경우 자신의 팩터리를 구현하는 것이 간단한 작업이어야 한다는 것입니다. 예를 들어 파생된 ServiceHostFactory값을 반환하는 사용자 지정 ServiceHost 은 다음과 같습니다.
public class DerivedFactory : ServiceHostFactory
{
public override ServiceHost CreateServiceHost( Type t, Uri[] baseAddresses )
{
return new DerivedHost( t, baseAddresses )
}
}
기본 팩터리 대신 이 팩터리를 사용하려면 다음과 같이 지시문에 @ServiceHost 형식 이름을 입력합니다.
<% @ServiceHost Factory="DerivedFactory" Service="MyService" %>
ServiceHost에서 반환되는 CreateServiceHost에 원하는 작업을 수행하는 데는 기술적 제한이 없지만, 팩터리 메서드의 구현을 가능한 한 간단하게 유지하는 것이 좋습니다. 사용자 지정 논리가 많은 경우 다시 사용할 수 있도록 팩터리 내부가 아닌 호스트 내부에 해당 논리를 배치하는 것이 좋습니다.
여기에 언급해야 하는 호스팅 API에 대한 계층이 하나 더 있습니다. 또한 WCF에는 ServiceHostBase에서 각각 파생된 ServiceHostFactoryBase와 ServiceHost에서 파생된 ServiceHostFactory가 있습니다. 이러한 시나리오는 메타데이터 시스템의 많은 부분을 사용자 지정된 만들기로 교체해야 하는 고급 시나리오에 존재합니다.