다음을 통해 공유


Known Types

이 샘플에서는 파생 형식에 대한 정보를 데이터 계약에서 지정하는 방법을 보여 줍니다. 데이터 계약을 사용하면 서비스와 구조적 데이터를 주고 받을 수 있습니다. 개체 지향 프로그래밍에서는 다른 형식에서 상속되는 형식을 원래 형식 대신에 사용할 수 있습니다. 서비스 지향 프로그래밍에서는 형식이 아닌 스키마가 전달되므로 형식 간의 관계가 유지되지 않습니다. 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);
}

클라이언트와 서비스 간에 전달할 수 있는 클래스의 필드를 나타내기 위해 DataContractAttributeDataMemberAttributeComplexNumber 클래스에 적용됩니다. ComplexNumber 대신 파생 ComplexNumberWithMagnitude 클래스를 사용할 수 있습니다. ComplexNumber 형식의 KnownTypeAttribute 특성에서 이를 나타냅니다.

[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);
    }
}

클라이언트에서 서비스 계약과 데이터 계약은 둘 다 서비스 메타데이터에서 Service Metadata Utility Tool (Svcutil.exe)에 의해 생성되는 generatedClient.cs 소스 파일에 정의됩니다. KnownTypeAttribute 특성이 서비스의 데이터 계약에 지정되므로 클라이언트는 서비스를 사용할 때 ComplexNumberComplexNumberWithMagnitude 클래스를 둘 다 받을 수 있습니다. 클라이언트는 ComplexNumberWithMagnitude를 가져왔는지 감지하고 적절한 출력을 생성합니다.

// Create a client
DataContractCalculatorClient client =     new DataContractCalculatorClient();

// Call the Add service operation.
ComplexNumber value1 = new ComplexNumber(); value1.real = 1; value1.imaginary = 2;
ComplexNumber value2 = new ComplexNumber(); value2.real = 3; value2.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.

샘플을 설치, 빌드 및 실행하려면

  1. Windows Communication Foundation 샘플의 일회 설치 절차를 수행했는지 확인합니다.

  2. C# 또는 Visual Basic .NET 버전의 솔루션을 빌드하려면 Windows Communication Foundation 샘플 빌드의 지침을 따릅니다.

  3. 단일 컴퓨터 또는 다중 컴퓨터 구성에서 샘플을 실행하려면 Windows Communication Foundation 샘플 실행의 지침을 따릅니다.

Send comments about this topic to Microsoft.
© 2007 Microsoft Corporation. All rights reserved.