2013-10-31 8 views
1

단순한 구성 (즉, 구성 파일에 명시적인 <service> 노드 없음)을 사용하여 동일한 클래스에서 IIS를 통해 제공되는 많은 양의 서비스 계약이 구현되었습니다.간소화 된 구성을위한 Wcf 끝점 사용자 지정

우리는 클라이언트에 동일한 URL을 가리키는 끝점을 자동으로 작성하는 논리가 있기 때문에 문제가 없습니다.

이제 클라이언트와 서버의 계약 중 하나를 사용자 정의하고 싶습니다. 나머지는 완전히 다릅니다. 이 특별 계약 클래스에 대해 스트리밍 전송을 사용하고 싶습니다. 반환하기도하고 Stream 인스턴스를 가져 오기도합니다.

서버에 <service> 노드를 추가하려고하면 공유 구현 클래스를 가리키고이 특수 계약 인터페이스를 사용하여 다른 서비스의 전체 자동 구성이 손실되고 단일 노출 된 서비스. 이것은 하나의 구현 클래스를 사용한다는 사실과 관련이 있다고 생각합니다. 그리고 Wcf가 설정에 클래스 이름을 가진 서비스가 있음을 감지하자마자 다른 계약의 끝점을 자동 생성하는 것을 중지합니다.

동일한 클래스를 공유하고 단순화 된 구성을 유지하면서이 방법을 사용할 수 있습니까?

답변

1

사용자 고유의 서비스 팩토리를 만들고 활성화 프로세스의 일부를 무시하여이 작업을 수행 할 수 있습니다.

이와 같이 두 가지 서비스 계약이 있다고 가정합니다.

public interface IService1 
{ 
    [OperationContract] 
    string GetData(int value); 
} 

[ServiceContract] 
public interface IService2 
{ 
    [OperationContract] 
    string Foobar(); 
} 

이러한 것들은 이와 같은 단일 클래스로 구현된다고 가정하십시오. 이제

public class Service1 : IService1, IService2 
{ 
    public string GetData(int value) 
    { 
     return string.Format("You entered: {0}", value); 
    } 
    public string Foobar() 
    { 
     return "foobar"; 
    } 
} 

, 당신은, 당신의 SVC는 파일, 단지 제 2 서비스 계약에 대한 엔드 포인트를 변경하려면 사용자 정의 서비스 공장 구현을 가리 키도록 공장 속성을 추가합니다.

<%@ ServiceHost Language="C#" Debug="true" Factory="SimpleWCF2.MyServiceFactory" Service="SimpleWCF2.Service1" CodeBehind="Service1.svc.cs" %> 

다음으로 사용자 지정 서비스 호스트를 인스턴스화하는 사용자 지정 서비스 팩터 리를 만듭니다. 사용자 정의 서비스 호스트에서 ApplyConfiguration을 대체하고 장기 구매 계약 2의 기본 엔드 포인트를 제거하고이를 사용자 정의 엔드 포인트 구성으로 바꾸십시오. 예를 들어 여기서는 계약 2에 대해서만 "basicHttpBinding"을 "WsHttpBinding"으로 대체합니다. 물론 바인딩을 구성 할 수는 있지만 (스트리밍에 대해 언급 했음) - 이것은 예제 일뿐입니다.

public class MyServiceFactory : ServiceHostFactory 
{ 
    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses) 
    { 
     return new MyServiceHost(serviceType, baseAddresses); 
    } 
} 

public class MyServiceHost : ServiceHost 
{ 
    public MyServiceHost(Type serviceType, params Uri[] baseAddresses) : 
     base (serviceType, baseAddresses) 
    { } 

    protected override void ApplyConfiguration() 
    { 
     base.ApplyConfiguration(); 

     AddDefaultEndpoints(); 

     // Remove the default endpoint for IService2 
     var defaultEp = this.Description.Endpoints.FirstOrDefault(e => e.Contract.ContractType == typeof(IService2)); 
     this.Description.Endpoints.Remove(defaultEp); 

     // Add a new custom endpoint for IService2 
     this.AddServiceEndpoint(typeof(IService2), new WSHttpBinding(), "test"); 
    } 
} 

그게 전부입니다. 단순화 된 구성을 변경하지 않아도됩니다.

이제 고객은 새 서비스 엔드 포인트를 통해 두 번째 계약을 발견하게됩니다. 예를 들어, 내 샘플의 WCF Test Client가 있습니다. 나는 공장 시스템이 어떻게 작동하는지 알고 있어요으로 수행

enter image description here

+0

는 나에게 의미가 있습니다. 나는 이것을 확장 할 수 없다고 걱정하고있다. 일반적인 '' 노드를 통해 설정을해야하지만 기본 엔드 포인트 자동 생성은 그대로 유지해야한다. 예를 들어, 50 개 서비스 중 5 개가 특별 맞춤 설정이 필요한 경우 어떻게됩니까? 이것은 유지 보수의 악몽이 될 것입니다. – julealgon

+1

글쎄, 내 첫 번째 응답 (나는 이것을 대체했다)에 대해 이야기했다. 어쩌면 나는 그것을 놓아 두었어야했다.:) 어쨌든 기본적으로 고유 한 서비스 계약을 자체 서비스 (.svc)로 분리해야합니다. 이렇게하면 다른 모든 서비스에 대해 기본 구성을 계속 사용할 수 있으며 고유 서비스에 대한 구성을 명시 적으로 정의 할 수 있습니다. 그러나 문제는 (당신이 그것으로 멋지다면) 당신은 이제 하나 이상의 진입 점을 갖게된다는 것입니다. 예를 들어, 대부분의 서비스 계약에는 ~/defaultservice.svc, 다른 서비스 계약에는 ~/uniqueservice1.svc가 있습니다. –

+0

하나의 진입 점이 있다는 사실은 정확히 동일한 클래스의 모든 서비스를 구현하기로 선택한 이유입니다. 나는 아직 대답해야하지만 이것은 [this] (http://stackoverflow.com/questions/19016659/simplified-wcf-configuration-on-server-and-client)와 관련된 질문이다. 이 새로운 접근 방식이 우리에게 훨씬 간단하므로 여러 URL을 관리해야하는 것을 최대한 피하고 싶습니다. 그것을 고려할 때 대안이 있습니까? – julealgon