Host Layanan Kustom
Sampel CustomServiceHost mendemonstrasikan cara menggunakan turunan kustom kelas ServiceHost untuk mengubah perilaku run-time sebuah layanan. Pendekatan ini menyediakan alternatif yang dapat digunakan kembali untuk mengonfigurasi sejumlah besar layanan dengan cara yang sama. Sampel ini juga menunjukkan cara menggunakan kelas ServiceHostFactory untuk menggunakan ServiceHost kustom di lingkungan hosting Layanan Informasi Internet (IIS) atau Layanan Aktivasi Proses Windows (WAS).
Tentang skenario
Untuk mencegah pengungkapan metadata layanan yang berpotensi sensitif secara tidak disengaja, konfigurasi default untuk layanan Windows Communication Foundation (WCF) menonaktifkan penerbitan metadata. Perilaku ini aman secara default, tetapi juga berarti Anda tidak dapat menggunakan alat impor metadata (seperti Svcutil.exe) untuk menghasilkan kode klien yang diperlukan untuk memanggil layanan kecuali perilaku penerbitan metadata layanan diaktifkan secara eksplisit dalam konfigurasi.
Mengaktifkan penerbitan metadata untuk sejumlah besar layanan melibatkan penambahan elemen konfigurasi yang sama ke setiap layanan individual, yang menghasilkan sejumlah besar informasi konfigurasi yang pada dasarnya sama. Sebagai alternatif untuk mengonfigurasi setiap layanan satu per satu, dimungkinkan untuk menulis kode imperatif yang memungkinkan penerbitan metadata sekali dan kemudian menggunakan kembali kode tersebut di beberapa layanan yang berbeda. Hal ini dicapai dengan membuat kelas baru yang berasal dari ServiceHost dan mengambil alih metode ApplyConfiguration
() untuk secara imperatif menambahkan perilaku penerbitan metadata.
Penting
Untuk kejelasan, contoh ini menunjukkan cara membuat titik akhir penerbitan metadata yang tidak aman. Titik akhir tersebut berpotensi tersedia untuk konsumen anonim yang tidak diautentikasi dan perawatan harus diambil sebelum menyebarkan titik akhir tersebut untuk memastikan bahwa pengungkapan metadata layanan secara publik sesuai.
Menerapkan ServiceHost kustom
Kelas ServiceHost ini memaparkan beberapa metode virtual yang berguna di mana metode tersebut dapat diambil alih oleh pewaris untuk mengubah perilaku run-time layanan. Misalnya, metode ApplyConfiguration
() membaca informasi konfigurasi layanan dari penyimpanan konfigurasi dan mengubah ServiceDescription host yang sesuai. Implementasi default membaca konfigurasi dari file konfigurasi aplikasi. Implementasi kustom dapat mengambil alih ApplyConfiguration
() untuk lebih jauh lagi melakukan perubahan ServiceDescription dalam penggunaan kode imperatif atau bahkan mengganti penyimpanan konfigurasi default sepenuhnya. Misalnya, untuk membaca konfigurasi titik akhir layanan dari database alih-alih file konfigurasi aplikasi.
Dalam sampel ini, kami ingin membangun ServiceHost kustom yang menambahkan ServiceMetadataBehavior (yang memungkinkan penerbitan metadata) bahkan jika perilaku ini tidak ditambahkan secara eksplisit dalam file konfigurasi layanan. Untuk mencapai hal ini, buat kelas baru yang mewarisi dari ServiceHost dan mengambil alih ApplyConfiguration
().
class SelfDescribingServiceHost : ServiceHost
{
public SelfDescribingServiceHost(Type serviceType, params Uri[] baseAddresses)
: base(serviceType, baseAddresses) { }
//Overriding ApplyConfiguration() allows us to
//alter the ServiceDescription prior to opening
//the service host.
protected override void ApplyConfiguration()
{
//First, we call base.ApplyConfiguration()
//to read any configuration that was provided for
//the service we're hosting. After this call,
//this.Description describes the service
//as it was configured.
base.ApplyConfiguration();
//(rest of implementation elided for clarity)
}
}
Karena kami tidak ingin mengabaikan konfigurasi apa pun yang telah disediakan dalam file konfigurasi aplikasi, hal pertama yang dilakukan oleh pengambil alihan ApplyConfiguration
() kami adalah memanggil implementasi dasar. Setelah metode ini selesai, kita dapat secara imperatif menambahkan ServiceMetadataBehavior ke deskripsi menggunakan kode imperatif berikut.
ServiceMetadataBehavior mexBehavior = this.Description.Behaviors.Find<ServiceMetadataBehavior>();
if (mexBehavior == null)
{
mexBehavior = new ServiceMetadataBehavior();
this.Description.Behaviors.Add(mexBehavior);
}
else
{
//Metadata behavior has already been configured,
//so we do not have any work to do.
return;
}
Hal terakhir yang harus dilakukan ketika kami melakukan ambil alih ApplyConfiguration
() adalah menambahkan titik akhir metadata default. Menurut konvensi, satu titik akhir metadata dibuat untuk setiap URI dalam koleksi BaseAddresses host layanan.
//Add a metadata endpoint at each base address
//using the "/mex" addressing convention
foreach (Uri baseAddress in this.BaseAddresses)
{
if (baseAddress.Scheme == Uri.UriSchemeHttp)
{
mexBehavior.HttpGetEnabled = true;
this.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName,
MetadataExchangeBindings.CreateMexHttpBinding(),
"mex");
}
else if (baseAddress.Scheme == Uri.UriSchemeHttps)
{
mexBehavior.HttpsGetEnabled = true;
this.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName,
MetadataExchangeBindings.CreateMexHttpsBinding(),
"mex");
}
else if (baseAddress.Scheme == Uri.UriSchemeNetPipe)
{
this.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName,
MetadataExchangeBindings.CreateMexNamedPipeBinding(),
"mex");
}
else if (baseAddress.Scheme == Uri.UriSchemeNetTcp)
{
this.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName,
MetadataExchangeBindings.CreateMexTcpBinding(),
"mex");
}
}
Menggunakan ServiceHost kustom di host mandiri
Sekarang setelah kami menyelesaikan implementasi ServiceHost kustom, kami dapat menggunakannya untuk menambahkan perilaku penerbitan metadata ke layanan apa pun dengan menghosting layanan tersebut di dalam instans SelfDescribingServiceHost
kami. Kode berikut menunjukkan cara menggunakannya dalam skenario host mandiri.
SelfDescribingServiceHost host =
new SelfDescribingServiceHost( typeof( Calculator ) );
host.Open();
Host kustom kami masih membaca konfigurasi titik akhir layanan dari file konfigurasi aplikasi, seolah-olah kami telah menggunakan kelas ServiceHost default untuk menghosting layanan. Namun, karena kami menambahkan logika untuk mengaktifkan penerbitan metadata di dalam host kustom, kami tidak lagi harus secara eksplisit mengaktifkan perilaku penerbitan metadata dalam konfigurasi. Pendekatan ini memiliki keuntungan berbeda ketika Anda membangun aplikasi yang berisi beberapa layanan dan Anda ingin mengaktifkan penerbitan metadata pada masing-masing aplikasi tanpa menulis elemen konfigurasi yang sama berulang-ulang.
Menggunakan ServiceHost kustom di IIS atau WAS
Menggunakan host layanan kustom dalam skenario host mandiri sangat mudah, karena ini adalah kode aplikasi Anda yang pada akhirnya bertanggung jawab untuk membuat dan membuka instans host layanan. Namun, di lingkungan hosting IIS atau WAS, infrastruktur WCF secara dinamis membuat host layanan Anda sebagai respons terhadap pesan masuk. Host layanan kustom juga dapat digunakan di lingkungan hosting ini, tetapi mereka memerlukan beberapa kode tambahan dalam bentuk ServiceHostFactory. Kode berikut menunjukkan turunan dari ServiceHostFactory sesuatu yang mengembalikan instans kustom SelfDescribingServiceHost
kami.
public class SelfDescribingServiceHostFactory : ServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type serviceType,
Uri[] baseAddresses)
{
//All the custom factory does is return a new instance
//of our custom host class. The bulk of the custom logic should
//live in the custom host (as opposed to the factory)
//for maximum
//reuse value outside of the IIS/WAS hosting environment.
return new SelfDescribingServiceHost(serviceType,
baseAddresses);
}
}
Seperti yang Anda lihat, menerapkan ServiceHostFactory kustom sangatlah mudah. Semua logika kustom berada di dalam implementasi ServiceHost; pabrik tersebut mengembalikan instans kelas turunan.
Untuk menggunakan pabrik kustom dengan implementasi layanan, kita harus menambahkan beberapa metadata tambahan ke file .svc layanan.
<% @ServiceHost Service="Microsoft.ServiceModel.Samples.CalculatorService"
Factory="Microsoft.ServiceModel.Samples.SelfDescribingServiceHostFactory"
language=c# Debug="true" %>
Di sini kami telah menambahkan atribut Factory
tambahan ke arahan @ServiceHost
, dan meneruskan nama jenis runtime bahasa umum dari pabrik kustom kami sebagai nilai atribut. Ketika IIS atau WAS menerima pesan untuk layanan ini, infrastruktur hosting WCF terlebih dahulu membuat instans ServiceHostFactory dan kemudian membuat instans host layanan itu sendiri dengan memanggil ServiceHostFactory.CreateServiceHost()
.
Menjalankan sampel
Meskipun sampel ini menyediakan implementasi klien dan layanan yang berfungsi penuh, titik sampelnya adalah untuk mengilustrasikan cara mengubah perilaku run-time layanan melalui host kustom., lakukan langkah-langkah berikut:
Amati efek host kustom
Buka file Web.config layanan dan amati bahwa tidak ada konfigurasi yang secara eksplisit mengaktifkan metadata untuk layanan.
Buka file .svc layanan dan amati bahwa arahan @ServiceHostnya berisi atribut Factory yang menentukan nama ServiceHostFactory kustom.
Menyiapkan, membangun, dan menjalankan sampel
Pastikan Anda telah melakukan Prosedur Penyiapan Satu Kali untuk Sampel Windows Communication Foundation.
Untuk membangun solusi, ikuti instruksi dalam Membangun Sampel Windows Communication Foundation.
Setelah solusi dibuat, jalankan Setup.bat untuk menyiapkan Aplikasi ServiceModelSamples di IIS 7.0. Direktori ServiceModelSamples sekarang akan muncul sebagai Aplikasi IIS 7.0.
Untuk menjalankan sampel dalam konfigurasi satu atau lintas komputer, ikuti instruksi pada Menjalankan Sampel WCF.
Untuk menghapus aplikasi IIS 7.0, jalankan Cleanup.bat.