Jenis yang Diketahui
Sampel KnownTypes menunjukkan cara menentukan informasi tentang jenis turunan dalam kontrak data. Kontrak data memungkinkan Anda meneruskan data terstruktur ke dan dari layanan. Dalam pemrograman berorientasi objek, jenis yang mewarisi dari jenis lain dapat digunakan sebagai pengganti jenis aslinya. Dalam pemrograman berorientasi layanan, skema selain jenis dikomunikasikan dan oleh karena itu, hubungan antara jenis tidak dipertahankan. Atribut KnownTypeAttribute memungkinkan informasi tentang jenis turunan disertakan dalam kontrak data. Jika mekanisme ini tidak digunakan, jenis turunan tidak dapat dikirim atau diterima di mana jenis dasar diharapkan.
Catatan
Prosedur penyiapan dan petunjuk pembuatan untuk sampel ini terdapat di akhir topik ini.
Kontrak layanan untuk layanan menggunakan nomor kompleks, seperti yang ditunjukkan dalam contoh kode berikut.
// 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 dan DataMemberAttribute diterapkan ke kelas ComplexNumber
untuk menunjukkan bidang kelas mana yang dapat diteruskan antara klien dan layanan. Kelas ComplexNumberWithMagnitude
turunan dapat digunakan sebagai pengganti ComplexNumber
. Atribut KnownTypeAttribute pada ComplexNumber
jenis menunjukkan ini.
[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;
}
}
Jenis ComplexNumberWithMagnitude
berasal dari ComplexNumber
tapi menambahkan anggota data tambahan, 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(); }
}
}
Untuk menunjukkan fitur jenis yang diketahui, layanan diimplementasikan sedemikian rupa sehingga hanya menampilkan ComplexNumberWithMagnitude
untuk penambahan dan pengurangan. (Meskipun kontrak menentukan ComplexNumber
, ini diizinkan karena atribut KnownTypeAttribute
). Perkalian dan pembagian masih menampilkan jenis ComplexNumber
dasar.
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);
}
}
Pada klien, Kontrak layanan dan kontrak data ditentukan dalam file sumber generatedClient.cs, yang dihasilkan oleh Alat Utilitas Metadata ServiceModel (Svcutil.exe) dari metadata layanan. Karena atribut KnownTypeAttribute ditentukan dalam kontrak data layanan, klien dapat menerima kelas ComplexNumber
dan ComplexNumberWithMagnitude
saat menggunakan layanan. Klien mendeteksi apakah ComplexNumberWithMagnitude
didapatkan dan menghasilkan output yang sesuai:
// 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");
}
Saat Anda menjalankan sampel, permintaan dan tanggapan operasi ditampilkan di jendela konsol klien. Perhatikan bahwa besaran dicetak untuk penambahan dan pengurangan tetapi tidak untuk perkalian dan pembagian karena cara layanan diimplementasikan. Tekan ENTER di jendela klien untuk mematikan komputer klien.
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.
Untuk menyiapkan, membangun, dan menjalankan sampel
Pastikan Anda telah melakukan Prosedur Penyiapan Satu Kali untuk Sampel Windows Communication Foundation.
Untuk membangun solusi edisi C# atau Visual Basic .NET, ikuti petunjuknya di Membangun Sampel WCF.
Untuk menjalankan sampel dalam konfigurasi satu atau lintas komputer, ikuti instruksi pada Menjalankan Sampel WCF.