이 질문은 시간이 지나면 쉽게 진화 할 수 있도록 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
어셈블리의 일부를 포함 할 수있다 및 붙여 넣기).지금의 어려움을 직면하고있는 두 번째 구현 질문
, 어떻게 업데이트하나요 내 DataContract
및 ServiceContracts
?
동일한 어셈블리를 업데이트하고 버전 번호를 증가합니까? 모든 클라이언트가 업그레이드하는 동안 어떻게 이전 버전과의 호환성을 유지합니까? 클라이언트가 업데이트 될 때까지 깨는 것은 허용되지 않습니다.
MyDataContract
을 확장하는 클래스로 새 어셈블리를 만들고 새 형식을 새로운ServiceContract
아래에서 허용하는 새 메서드를 만드나요? 그것은 새로운 계약이 필요한 계약에 대한 모든 사소한 변경을 의미합니까? 몇 년 후에 문자 그대로 수백 가지가되는 것을 어떻게 막을 수 있습니까?다른 해결책은 있습니까?
내가 생각하는 해결책에 관계없이 모두 큰 단점을 갖고있는 것처럼 보입니다.
- 클라이언트 소프트웨어가 시간이 지남에 따라 발전함에 따라
- 는 고객이 더 팽창 트림 유지 업데이트 할 때까지 호환성 이전 버전과 보존의 (적어도 나에게)이있을 것 같지 않습니다
- 내
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은 틀린 것처럼 보였으 나, 이것을 테스트했을 때 오래된 클라이언트에서 서비스는 실제로 하위 호환이 가능합니다.
, 감사합니다! –
@ marc-s 같은 계약 이름을 유지할 수있는 것 같지 않습니까? –
@MAfifi : 아니오 - 당신도 마찬가지입니다! 서비스 계약과 같은 인터페이스가 ** 불변 **이라는 기본 원칙입니다. 뭔가를 추가해야하는 경우 새로운 이름을 지정해야합니다. 물론 기존 인터페이스를 깨뜨리지 않아야합니다. 매개 변수의 수 또는 데이터 유형 ... –