2012-05-29 3 views
5

이 질문은 시간이 지나면 쉽게 진화 할 수 있도록 WCF 서비스를 설계하는 방법에 관한 것입니다. 문제를 설명하지 않고 이에 대한 응답의 깊이를 얻기가 어렵습니다.WCF 아키텍처 및 버전

내가 WCF 서비스와 클라이언트의 대형 시스템을 개발하고

배경입니다. 이 코드를 실행하는 데 문제가있는 서버가 10 개뿐이기 때문에 서버 측은 쉽게 업데이트 할 수 있습니다.

고도의 자동화에도 불구하고 300,000 이상의 WCF 클라이언트에서 클라이언트를 업데이트하는 것은 매우 어렵습니다. 업데이트는 항상 시간이 걸리고 2 ~ 3 주에 걸쳐 높은 업데이트 성공률을 달성합니다 .

데이터

[DataContract] 
public class MyContract 
{ 
    [DataMember] 
    public int Identity {get; set;} 

    [DataMember] 
    public string Name {get; set;} 

    // More members 
} 

DataContract는 초기화하기 어려운 계약과 컴퓨터에 해당하는 인스턴스를 얻을 초기화하는 표준 MyContractFactory 클래스가 있습니다.

public class static MyContractFactory 
{ 
    public static MyContract GetMyContract() 
    { 
     // Complex implementation 
    } 
} 

ServiceContracts

DataContract 웹 서비스의 범위에 걸쳐 매우 일반적입니다.

namespace MyPrefix.WebServicve1 
{ 
    [ServiceContract] 
    public class IMyInterface1 
    { 
     [OperationContract] 
     public void DoSomethingWithMyContract(MyContract data); 
    } 

    [ServiceContract] 
    public class IMyInterface2 
    { 
     [OperationContract] 
     public void DoSomethingDifferentWithMyContract(MyContract data); 
    } 
} 

클라이언트는

제 의뢰인은 우리가 플러그인에있는 신뢰의 수준에 따라 별도의 프로세스 또는 응용 프로그램 도메인 중 하나에서 실행되는 플러그인에 기반 플러그인입니다.

구현 한

이 (기본 WCF)의 내 초기 구현 자체 조립 한 조립, ServiceContract 및 구현에 DataContract으로 돌아가 셨습니다.

클라이언트는 거의 모든 플러그인에 매우 추한으로 MyContractFactory의 복사 및 붙여 넣기와

MyWebService1.MyContract 
MyWebService2.MyContract 

을했다. DataContract은 동일했지만 클라이언트가 DataContract 어셈블리를 포함하지 않았다는 사실은 다른 개체로 다른 네임 스페이스에 나타났습니다.

구현이

클라이언트가 이제 DataContract 어셈블리를 포함, ServiceContracts가 서비스 구현에 별도의 조립에이 코드를 재사용 (더 이상 사본과 함께 도움이 될 경우, 클라이언트는 ServiceContract 어셈블리의 일부를 포함 할 수있다 및 붙여 넣기).지금의 어려움을 직면하고있는 두 번째 구현 질문

, 어떻게 업데이트하나요 내 DataContractServiceContracts?

  1. 동일한 어셈블리를 업데이트하고 버전 번호를 증가합니까? 모든 클라이언트가 업그레이드하는 동안 어떻게 이전 버전과의 호환성을 유지합니까? 클라이언트가 업데이트 될 때까지 깨는 것은 허용되지 않습니다.

  2. MyDataContract을 확장하는 클래스로 새 어셈블리를 만들고 새 형식을 새로운 ServiceContract 아래에서 허용하는 새 메서드를 만드나요? 그것은 새로운 계약이 필요한 계약에 대한 모든 사소한 변경을 의미합니까? 몇 년 후에 문자 그대로 수백 가지가되는 것을 어떻게 막을 수 있습니까?

  3. 다른 해결책은 있습니까?

내가 생각하는 해결책에 관계없이 모두 큰 단점을 갖고있는 것처럼 보입니다.

  • 클라이언트 소프트웨어가 시간이 지남에 따라 발전함에 따라
  • 는 고객이 더 팽창 트림 유지 업데이트 할 때까지 호환성 이전 버전과 보존의 (적어도 나에게)이있을 것 같지 않습니다
  • ServiceContract을 심각하게 오염시키지 않습니다 (OperationContract의 과부하는 새로운 "이름"이 필요함). 나는 이미 아래와 같은 것들을 가지고 있으며, 시간이 지남에 따라 악몽을 꾼다.

나는 대규모 환경에서 일정 기간 동안 일했다 솔루션을 찾고 있어요

[OperationContract] 
public void DoSomethingWithMyContract(MyContract data); 

[OperationContract(Name = "DoSomethingWithMyDataByAdditionalData"] 
public void DoSomethingWithMyContract(MyContract data, MyContract2 additionalData); 

운영 계약의 복잡성. 블로그 항목 등은 매우 환영합니다.

업데이트 1

"스키마"변경을 사용의 한계를 통해 찾고는, 다른 네임 스페이스가 유일하고 확실한 방법처럼 보인다. 그러나 예상대로 작동하지 않습니다.다음 서비스

public class MyService : IServiceContract1, IServiceContract2 
{ 
    // Implement both operations 
} 

다음과 같은 설정이 다른 이름을 가진이 계약에

<service behaviorConfiguration="WcfServiceTests.ServiceBehavior" 
    name="Test.MyService"> 
    <endpoint 
     address="2012/05" 
     binding="wsHttpBinding" 
     contract="Test.IServiceContract1"> 
     <identity> 
     <dns value="localhost" /> 
     </identity> 
    </endpoint> 
    <endpoint 
     address="2012/06" 
     binding="wsHttpBinding" 
     contract="Test.IServiceContract2"> 
     <identity> 
     <dns value="localhost" /> 
     </identity> 
    </endpoint> 
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 
    </service> 

결과

[ServiceContract(
    Name = "IServiceContract", 
    Namespace = "http://myurl/2012/05")] 
public interface IServiceContract1 
{ 
    // Some operations 
} 

[ServiceContract(
    Name = "IServiceContract", 
    Namespace = "http://myurl/2012/06")] 
public interface IServiceContract2 
{ 
    // Some different operations using new DataContracts 
} 

아래, 나는 예상 나는 내 고객,

에 지점 수

http://myurl.com/MyService.svc/2012/05 이전 버전은 http://myurl.com/MyService.svc/2012/06

하지만 ServiceContract 이름을 보존하려는 경우 동일한 서비스에 대한 별도의 종단점 주소가 아닌 두 개의 별도 서비스가 있어야하는 것처럼 보입니까?

업데이트 2

내가 업데이트 1에서 기술 한 방법을 사용하여 끝났다. WSDL은 틀린 것처럼 보였으 나, 이것을 테스트했을 때 오래된 클라이언트에서 서비스는 실제로 하위 호환이 가능합니다.

답변

5

마이크로 소프트와 존중받는 WCF 전문가 모두는 아마도 같은 것을 말할 것입니다. 버전 관리는 네임 스페이스 계약을 사용하여 처리해야합니다. 내가 실제 WCF 서비스 (및 데이터 계약)을 의미하는 네임 스페이스를 - -

나는 당신의 어셈블리의 .NET 네임 스페이스를 의미하지 않는다 그래서 당신은해야한다 : - 몇몇 사람 같은

[ServiceContract(Namespace="http://services.yourcompany.com/Service1/V01"] 

를 등 뭔가 연도 별 버전/월 :

[ServiceContract(Namespace="http://services.yourcompany.com/Service1/2012/05"] 

이 같은 서비스의 여러 버전을 가질 수 있으며, 한 클라이언트 (서비스 네임 스페이스로 표시) 이전 버전과 전화 와서, 그들은이를 얻을 수 있습니다 이전 버전 (여전히 당신이 노출하는 한).

은보기 : 해당 링크의 마크-의 훌륭한 답변 @

+0

, 감사합니다! –

+0

@ marc-s 같은 계약 이름을 유지할 수있는 것 같지 않습니까? –

+1

@MAfifi : 아니오 - 당신도 마찬가지입니다! 서비스 계약과 같은 인터페이스가 ** 불변 **이라는 기본 원칙입니다. 뭔가를 추가해야하는 경우 새로운 이름을 지정해야합니다. 물론 기존 인터페이스를 깨뜨리지 않아야합니다. 매개 변수의 수 또는 데이터 유형 ... –

관련 문제