Bekende typen
Het voorbeeld KnownTypes laat zien hoe u informatie over afgeleide typen in een gegevenscontract opgeeft. Met gegevenscontracten kunt u gestructureerde gegevens doorgeven aan en van services. In objectgeoriënteerde programmering kan een type dat van een ander type overkomt, worden gebruikt in plaats van het oorspronkelijke type. In servicegeoriënteerde programmering worden schema's in plaats van typen gecommuniceerd en daarom blijft de relatie tussen typen niet behouden. Met KnownTypeAttribute het kenmerk kan informatie over afgeleide typen worden opgenomen in het gegevenscontract. Als dit mechanisme niet wordt gebruikt, kan een afgeleid type niet worden verzonden of ontvangen waar een basistype wordt verwacht.
Notitie
De installatieprocedure en build-instructies voor dit voorbeeld bevinden zich aan het einde van dit onderwerp.
Het servicecontract voor de service maakt gebruik van complexe getallen, zoals wordt weergegeven in de volgende voorbeeldcode.
// 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);
}
De DataContractAttribute en DataMemberAttribute wordt toegepast op de ComplexNumber
klasse om aan te geven welke velden van de klasse kunnen worden doorgegeven tussen de client en de service. De afgeleide ComplexNumberWithMagnitude
klasse kan worden gebruikt in plaats van ComplexNumber
. Het KnownTypeAttribute kenmerk van het ComplexNumber
type geeft dit aan.
[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;
}
}
Het ComplexNumberWithMagnitude
type is afgeleid van ComplexNumber
maar voegt een extra gegevenslid toe. 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(); }
}
}
Om de functie bekende typen te demonstreren, wordt de service zodanig geïmplementeerd dat deze alleen een ComplexNumberWithMagnitude
functie voor optellen en aftrekken retourneert. (Hoewel het contract aangeeft ComplexNumber
, is dit toegestaan vanwege het KnownTypeAttribute
kenmerk). Vermenigvuldiging en deling retourneren nog steeds het basistype 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);
}
}
Op de client worden zowel het servicecontract als het gegevenscontract gedefinieerd in het bronbestand generatedClient.cs, dat wordt gegenereerd door het hulpprogramma ServiceModel Metadata Utility (Svcutil.exe) op basis van servicemetagegevens. Omdat het KnownTypeAttribute kenmerk is opgegeven in het gegevenscontract van de service, kan de client zowel de als ComplexNumberWithMagnitude
de ComplexNumber
klassen ontvangen wanneer de service wordt gebruikt. De client detecteert of er een ComplexNumberWithMagnitude
en de juiste uitvoer wordt gegenereerd:
// 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");
}
Wanneer u het voorbeeld uitvoert, worden de aanvragen en antwoorden van de bewerking weergegeven in het clientconsolevenster. Houd er rekening mee dat een grootte wordt afgedrukt voor optellen en aftrekken, maar niet voor vermenigvuldigen en delen vanwege de manier waarop de service is geïmplementeerd. Druk op Enter in het clientvenster om de client af te sluiten.
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.
Het voorbeeld instellen, compileren en uitvoeren
Zorg ervoor dat u de eenmalige installatieprocedure voor de Windows Communication Foundation-voorbeelden hebt uitgevoerd.
Als u de C# of Visual Basic .NET-editie van de oplossing wilt bouwen, volgt u de instructies in het bouwen van de Windows Communication Foundation-voorbeelden.
Als u het voorbeeld wilt uitvoeren in een configuratie met één of meerdere computers, volgt u de instructies in Het uitvoeren van de Windows Communication Foundation-voorbeelden.