Memperluas Hosting Menggunakan ServiceHostFactory
API ServiceHost standar untuk layanan hosting di Windows Communication Foundation (WCF) adalah titik ekstensibilitas dalam arsitektur WCF. Pengguna dapat memperoleh kelas host mereka sendiri dari ServiceHost, biasanya untuk mengambil alih OnOpening() untuk menggunakan ServiceDescription guna menambahkan titik akhir default secara imperatif atau memodifikasi perilaku, sebelum membuka layanan.
Di lingkungan host mandiri, Anda tidak perlu membuat ServiceHost kustom karena Anda menulis kode yang membuat instans host dan kemudian memanggil Open() pada kode itu setelah Anda membuat instans. Di antara dua langkah tersebut, Anda dapat melakukan apa pun yang Anda inginkan. Misalnya, Anda dapat menambahkan IServiceBehavior:
public static void Main()
{
ServiceHost host = new ServiceHost( typeof( MyService ) );
host.Description.Add( new MyServiceBehavior() );
host.Open();
...
}
Pendekatan ini tidak dapat digunakan kembali. Kode yang memanipulasi deskripsi dikodekan ke dalam program host (dalam hal ini, fungsi Main()), sehingga sulit untuk menggunakan kembali logika itu dalam konteks lain. Ada juga cara lain untuk menambahkan IServiceBehavior yang tidak memerlukan kode imperatif. Anda dapat menurunkan atribut dari ServiceBehaviorAttribute dan meletakkannya pada jenis implementasi layanan Anda atau Anda dapat membuat perilaku kustom menjadi dapat dikonfigurasi dan menyusunnya secara dinamis menggunakan konfigurasi.
Namun, sedikit variasi dari contoh juga dapat digunakan untuk memecahkan masalah ini. Salah satu pendekatannya adalah memindahkan kode yang menambahkan ServiceBehavior dari Main()
dan ke dalam metode OnOpening pada turunan kustom dari ServiceHost:
public class DerivedHost : ServiceHost
{
public DerivedHost( Type t, params Uri baseAddresses ) :
base( t, baseAddresses ) {}
public override void OnOpening()
{
this.Description.Add( new MyServiceBehavior() );
}
}
Kemudian, di dalam Main()
Anda dapat menggunakan:
public static void Main()
{
ServiceHost host = new DerivedHost( typeof( MyService ) );
host.Open();
...
}
Sekarang Anda telah menyertakan logika kustom ke dalam abstraksi bersih yang dapat dengan mudah digunakan kembali di banyak executable host yang berbeda.
Cara menggunakan kustom ServiceHost ini dari dalam Layanan Informasi Internet (IIS) atau Layanan Aktivasi Proses Windows (WAS) tidak langsung jelas. Lingkungan tersebut berbeda dari lingkungan host mandiri, karena lingkungan hosting adalah lingkungan yang membuat instans pada ServiceHost atas nama aplikasi. Infrastruktur hosting IIS dan WAS tidak tahu apa-apa tentang turunan ServiceHost kustom Anda.
ServiceHostFactory dirancang untuk menyelesaikan masalah ini dalam mengakses ServiceHost kustom Anda dari dalam IIS atau WAS. Karena host kustom yang diturunkan dari ServiceHost dikonfigurasi secara dinamis dan berpotensi dari berbagai jenis, lingkungan hosting tidak pernah membuat instans padanya secara langsung. Sebaliknya, WCF menggunakan pola pabrik untuk menyediakan lapisan tidak langsung antara lingkungan hosting dan jenis konkret layanan. Kecuali Anda memberi tahu sebaliknya, WCF menggunakan implementasi ServiceHostFactory default yang menampilkan instans ServiceHost. Tetapi Anda juga dapat menyediakan pabrik Anda sendiri yang menampilkan host turunan Anda dengan menentukan nama jenis CLR dari implementasi pabrik Anda dalam perintah @ServiceHost.
Niatnya adalah bahwa untuk kasus-kasus dasar, mengimplementasikan pabrik Anda sendiri seharusnya menjadi sebuah latihan. Misalnya, berikut adalah kustom ServiceHostFactory yang menampilkan ServiceHost turunan:
public class DerivedFactory : ServiceHostFactory
{
public override ServiceHost CreateServiceHost( Type t, Uri[] baseAddresses )
{
return new DerivedHost( t, baseAddresses )
}
}
Untuk menggunakan pabrik ini, bukan pabrik default, berikan nama jenis dalam perintah @ServiceHost sebagai berikut:
<% @ServiceHost Factory="DerivedFactory" Service="MyService" %>
Meskipun tidak ada batasan teknis untuk melakukan apa yang Anda inginkan pada ServiceHost yang ditampilkan dari CreateServiceHost, sebaiknya jaga implementasi pabrik Anda sesering mungkin. Jika Anda memiliki banyak logika kustom, lebih baik memasukkan logika itu ke dalam host Anda, bukan di dalam pabrik, sehingga dapat digunakan kembali.
Ada satu lapisan lagi untuk API hosting yang harus disebutkan di sini. WCF juga memiliki ServiceHostBase dan ServiceHostFactoryBase, yang secara berurutan memiliki turunan ServiceHost dan ServiceHostFactory. Hal ini ada untuk skenario yang lebih lanjut di mana Anda harus menukar sebagian besar sistem metadata dengan kreasi kustom Anda sendiri.