알려진 유형
KnownTypes 샘플에서는 파생 형식에 대한 정보를 데이터 계약에서 지정하는 방법을 보여 줍니다. 데이터 계약을 사용하면 서비스와 구조적 데이터를 주고 받을 수 있습니다. 개체 지향 프로그래밍에서는 다른 형식에서 상속되는 형식을 원래 형식 대신에 사용할 수 있습니다. 서비스 지향 프로그래밍에서는 형식이 아닌 스키마가 전달되므로 형식 간의 관계가 유지되지 않습니다. KnownTypeAttribute 특성을 사용하면 파생 형식에 대한 정보를 데이터 계약에 포함할 수 있습니다. 이 메커니즘이 사용되지 않을 경우 기본 형식이 필요한 곳에서 파생 형식을 주고 받을 수 없습니다.
참고 항목
이 샘플의 설치 절차 및 빌드 지침은 이 항목의 끝부분에 나와 있습니다.
다음 샘플 코드와 같이 서비스에 대한 서비스 계약에서는 복소수를 사용합니다.
// Define a service contract.
[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]
public interface ICalculator
{
[OperationContract]
ComplexNumber Add(ComplexNumber n1, ComplexNumber n2);
[OperationContract]
ComplexNumber Subtract(ComplexNumber n1, ComplexNumber n2);
[OperationContract]
ComplexNumber Multiply(ComplexNumber n1, ComplexNumber n2);
[OperationContract]
ComplexNumber Divide(ComplexNumber n1, ComplexNumber n2);
}
클라이언트와 서비스 간에 전달할 수 있는 클래스의 필드를 나타내기 위해 DataContractAttribute 및 DataMemberAttribute가 ComplexNumber
클래스에 적용됩니다. ComplexNumberWithMagnitude
대신 파생 ComplexNumber
클래스를 사용할 수 있습니다. KnownTypeAttribute 형식의 ComplexNumber
특성에서 이를 나타냅니다.
[DataContract(Namespace="http://Microsoft.ServiceModel.Samples")]
[KnownType(typeof(ComplexNumberWithMagnitude))]
public class ComplexNumber
{
[DataMember]
public double Real = 0.0D;
[DataMember]
public double Imaginary = 0.0D;
public ComplexNumber(double real, double imaginary)
{
this.Real = real;
this.Imaginary = imaginary;
}
}
ComplexNumberWithMagnitude
형식은 ComplexNumber
에서 파생되지만 추가 데이터 멤버인 Magnitude
를 추가합니다.
[DataContract(Namespace="http://Microsoft.ServiceModel.Samples")]
public class ComplexNumberWithMagnitude : ComplexNumber
{
public ComplexNumberWithMagnitude(double real, double imaginary) :
base(real, imaginary) { }
[DataMember]
public double Magnitude
{
get { return Math.Sqrt(Imaginary*Imaginary + Real*Real); }
set { throw new NotImplementedException(); }
}
}
알려진 형식 기능을 보여 주기 위해 더하기 및 빼기에 대해서만 ComplexNumberWithMagnitude
를 반환하는 방식으로 서비스가 구현됩니다. 계약에서 ComplexNumber
를 지정하지만 이는 KnownTypeAttribute
특성으로 인해 허용됩니다. 곱하기와 나누기는 계속 기본 ComplexNumber
형식을 반환합니다.
public class DataContractCalculatorService : IDataContractCalculator
{
public ComplexNumber Add(ComplexNumber n1, ComplexNumber n2)
{
//Return the derived type.
return new ComplexNumberWithMagnitude(n1.Real + n2.Real,
n1.Imaginary + n2.Imaginary);
}
public ComplexNumber Subtract(ComplexNumber n1, ComplexNumber n2)
{
//Return the derived type.
return new ComplexNumberWithMagnitude(n1.Real - n2.Real,
n1.Imaginary - n2.Imaginary);
}
public ComplexNumber Multiply(ComplexNumber n1, ComplexNumber n2)
{
double real1 = n1.Real * n2.Real;
double imaginary1 = n1.Real * n2.Imaginary;
double imaginary2 = n2.Real * n1.Imaginary;
double real2 = n1.Imaginary * n2.Imaginary * -1;
//Return the base type.
return new ComplexNumber(real1 + real2, imaginary1 +
imaginary2);
}
public ComplexNumber Divide(ComplexNumber n1, ComplexNumber n2)
{
ComplexNumber conjugate = new ComplexNumber(n2.Real,
-1*n2.Imaginary);
ComplexNumber numerator = Multiply(n1, conjugate);
ComplexNumber denominator = Multiply(n2, conjugate);
//Return the base type.
return new ComplexNumber(numerator.Real / denominator.Real,
numerator.Imaginary);
}
}
클라이언트에서 서비스 계약과 데이터 계약 모두 서비스 메타데이터에서 ServiceModel Metadata 유틸리티 도구(Svcutil.exe)에 의해 생성되는 소스 파일 generatedClient.cs에 정의됩니다. KnownTypeAttribute 특성이 서비스의 데이터 계약에 지정되므로 클라이언트는 서비스를 사용할 때 ComplexNumber
및 ComplexNumberWithMagnitude
클래스를 둘 다 받을 수 있습니다. 클라이언트는 ComplexNumberWithMagnitude
를 가져왔는지 감지하고 적절한 출력을 생성합니다.
// Create a client
DataContractCalculatorClient client =
new DataContractCalculatorClient();
// Call the Add service operation.
ComplexNumber value1 = new ComplexNumber() { real = 1, imaginary = 2 };
ComplexNumber value2 = new ComplexNumber() { real = 3, imaginary = 4 };
ComplexNumber result = client.Add(value1, value2);
Console.WriteLine("Add({0} + {1}i, {2} + {3}i) = {4} + {5}i",
value1.real, value1.imaginary, value2.real, value2.imaginary,
result.real, result.imaginary);
if (result is ComplexNumberWithMagnitude)
{
Console.WriteLine("Magnitude: {0}",
((ComplexNumberWithMagnitude)result).Magnitude);
}
else
{
Console.WriteLine("No magnitude was sent from the service");
}
샘플을 실행하면 작업의 요청 및 응답이 클라이언트 콘솔 창에 표시됩니다. 서비스가 구현된 방식으로 인해 크기는 더하기와 빼기의 경우 출력되지만 곱하기와 나누기의 경우 출력되지 않습니다. 클라이언트를 종료하려면 클라이언트 창에서 Enter 키를 누릅니다.
Add(1 + 2i, 3 + 4i) = 4 + 6i
Magnitude: 7.21110255092798
Subtract(1 + 2i, 3 + 4i) = -2 + -2i
Magnitude: 2.82842712474619
Multiply(2 + 3i, 4 + 7i) = -13 + 26i
No magnitude was sent from the service
Divide(3 + 7i, 5 + -2i) = 0.0344827586206897 + 41i
No magnitude was sent from the service
Press <ENTER> to terminate client.
샘플을 설치, 빌드 및 실행하려면
Windows Communication Foundation 샘플의 일회 설치 절차를 수행했는지 확인합니다.
C# 또는 Visual Basic .NET 버전의 솔루션을 빌드하려면 Building the Windows Communication Foundation Samples의 지침을 따릅니다.
단일 컴퓨터 또는 다중 컴퓨터 구성에서 샘플을 실행하려면 Windows Communication Foundation 샘플 실행의 지침을 따릅니다.