WCF 서비스의 반환 값으로 사용자 정의 객체를 사용한다.
WCF 서비스와 클라이언트의 데이터 계약을 위한 DataContract Attribute 설정을 통해 시리얼라이즈 되어 통신이 가능해 진다.
그런데 이 반환 객체의 멤버 중, Collection 타입의 멤버는 내부 Item 타입만 다를 뿐이라서 상위 타입 선언을 통해 하나의 클래스만 유지하고 싶었다.
예를 들어서 이런 식이다.
public class ReturnCollectionCategory : ReturnBaseObj
{
[DataMember]
public IList<Category> ResultCollection { get; set; }
}
[DataContract]
public class ReturnCollectionProduct : ReturnBaseObj
{
[DataMember]
public IList<Product> ResultCollection { get; set; }
}
위의 코드를 보면, ResultCollection 프로퍼티의 아이템 타입만 다를 뿐 나머지는 모두 동일하다.
따라서 최상위 타입인 System.Object로 아래와 같이 처리하려 했다
public class ReturnCollectionCategory : ReturnBaseObj
{
[DataMember]
public IList<System.Object> ResultCollection { get; set; }
}
이렇게 하면 하나의 클래스를 유지하면서 다형적으로 처리할 수 있게 된다.
그런데 문제는 WCF 환경에서 이 객체를 원격 통신용 객체로 이용할 때 발생한다. System.Object 타입을 시리얼라이즈 할 수 없다는 것이다.
그래서 아래와 같이 지네릭을 이용하기로 한다.
지네릭을 이용하면, 객체 생성 시점에 타입이 결정되기 때문에 원격 통신에도 문제없이 잘 동작한다.
public class ReturnCollectionObj<T> : ReturnBaseObj
{
[DataMember]
public IList<T> ResultCollection { get; set; }
}
추가로, 이렇게 서비스 단에서 지네릭 기반으로 생성된 객체를 원격으로 전달받는 클라이언트에서는 지네릭 버전이 아니라 이미 결정된 객체 이름으로 전달받게 된다.
즉 서비스 참조로 생성된 프록시 객체를 보면 지네릭 버전의 객체 이름에 임의의 문자열이 추가된 것을 확인할 수 있다. 실제 서비스 환경에서는 이러한 상황이 달갑지 않다.
따라서 아래와 같이 이름을 지정하면 좋을 것이다.
[DataContract(Name="ReturnCollectionObj{0}")]
public class ReturnCollectionObj<T> : ReturnBaseObj{
[DataMember]
public IList<T> ResultCollection { get; set; }
}
이렇게 하면 클라이언트에서 반환 받는 객체 이름은 타입이 결정된 이름이 붙여 진다.
예를 들어 Product 타입으로 객체를 생성했다면, ReturnCollectionObjProduct 가 된다.
'.NET Framework' 카테고리의 다른 글
serviceThrottling in WCF (4) | 2013.05.13 |
---|---|
Stored Procedure return value in Entity Framework (4) | 2013.05.09 |
WCF Data Service VS ASP.NET Web API (6) | 2013.01.08 |
LING to SQL에서 다중 결과 셋 받기 (4) | 2012.11.13 |
MVC 다중 폼 유효성 체크 (4) | 2012.09.07 |