Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Pola objek yang dapat diperluas digunakan untuk memperluas kelas runtime yang ada dengan fungsionalitas baru atau untuk menambahkan status baru ke objek. Ekstensi, yang melekat pada salah satu objek yang dapat diperluas, memungkinkan perilaku pada tahap yang sangat berbeda dalam pemrosesan untuk mengakses status bersama dan fungsionalitas yang melekat pada objek umum yang dapat mereka akses.
Pola IExtensibleObject<T>
Ada tiga antarmuka dalam pola objek yang dapat diperluas: IExtensibleObject<T>, , IExtension<T>dan IExtensionCollection<T>.
Antarmuka IExtensibleObject<T> diimplementasikan oleh jenis yang memungkinkan IExtension<T> objek untuk menyesuaikan fungsionalitasnya.
Objek yang dapat diperluas memungkinkan agregasi IExtension<T> objek yang dinamis. IExtension<T> objek dicirikan oleh antarmuka berikut:
public interface IExtension<T>
where T : IExtensibleObject<T>
{
void Attach(T owner);
void Detach(T owner);
}
Pembatasan jenis menjamin bahwa ekstensi hanya dapat didefinisikan untuk kelas yang adalah IExtensibleObject<T>. Attach dan Detach memberikan pemberitahuan agregasi atau disaggregasi.
Ini berlaku untuk implementasi untuk membatasi kapan mereka dapat ditambahkan dan dihapus dari pemilik. Misalnya, Anda dapat melarang penghapusan sepenuhnya, melarang penambahan atau penghapusan ekstensi saat pemilik atau ekstensi berada dalam status tertentu, melarang penambahan ke beberapa pemilik secara bersamaan, atau hanya mengizinkan satu penambahan diikuti dengan satu penghapusan.
IExtension<T> tidak menyiratkan interaksi apa pun dengan antarmuka terkelola standar lainnya. Secara khusus, IDisposable.Dispose metode pada objek pemilik biasanya tidak melepaskan ekstensinya.
Ketika ekstensi ditambahkan ke koleksi, Attach dipanggil sebelum masuk ke koleksi. Ketika ekstensi dihapus dari koleksi, Detach dipanggil setelah dihapus. Ini berarti (dengan asumsi sinkronisasi yang sesuai) ekstensi hanya dapat mengandalkan bahwa ia ditemukan dalam koleksi saat berada di antara Attach dan Detach.
Objek yang diteruskan ke FindAll atau Find tidak perlu berupa IExtension<T> (misalnya, Anda dapat meneruskan objek apa pun), tetapi ekstensi yang dikembalikan adalah IExtension<T>.
Jika tidak ada ekstensi dalam koleksi yang merupakan IExtension<T>, Find mengembalikan null, dan FindAll mengembalikan koleksi kosong. Jika beberapa ekstensi mengimplementasikan IExtension<T>, Find mengembalikan salah satunya. Nilai yang dikembalikan dari FindAll adalah rekam jepret.
Ada dua skenario utama. Skenario pertama menggunakan properti Extensions berbasis tipe sebagai kamus untuk menyisipkan status pada sebuah objek agar memungkinkan komponen lain untuk mencarinya berdasarkan tipe.
Skenario kedua menggunakan Attach properti dan Detach untuk memungkinkan objek berpartisipasi dalam perilaku kustom, seperti mendaftar untuk peristiwa, menonton transisi status, dan sebagainya.
Antarmuka IExtensionCollection<T> adalah kumpulan IExtension<T> objek yang memungkinkan pengambilan IExtension<T> berdasarkan tipe-nya. IExtensionCollection<T>.Find mengembalikan objek yang terakhir ditambahkan yang merupakan IExtension<T> jenis tersebut.
Objek yang Dapat Diperluas di Windows Communication Foundation
Ada empat objek yang dapat diperluas di Windows Communication Foundation (WCF):
ServiceHostBase – Ini adalah kelas dasar untuk host layanan. Ekstensi kelas ini dapat digunakan untuk memperluas perilaku ServiceHostBase dirinya sendiri atau untuk menyimpan status untuk setiap layanan.
InstanceContext – Kelas ini menghubungkan instans jenis layanan dengan runtime layanan. Ini berisi informasi tentang instans serta referensi ke InstanceContext yang berisi ServiceHostBase. Ekstensi kelas ini dapat digunakan untuk memperluas perilaku InstanceContext atau untuk menyimpan status untuk setiap layanan.
OperationContext – Kelas ini mewakili informasi operasi yang dikumpulkan runtime untuk setiap operasi. Ini termasuk informasi seperti header pesan masuk, properti pesan masuk, identitas keamanan masuk, dan informasi lainnya. Ekstensi kelas ini dapat memperluas perilaku OperationContext atau menyimpan status untuk setiap operasi.
IContextChannel – Antarmuka ini memungkinkan inspeksi setiap status untuk saluran dan proksi yang dibangun oleh runtime WCF. Ekstensi kelas ini dapat memperluas perilaku IClientChannel atau dapat menggunakannya untuk menyimpan status untuk setiap saluran.
Contoh kode berikut menunjukkan penggunaan ekstensi sederhana untuk melacak InstanceContext objek.
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Configuration;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
namespace Microsoft.WCF.Documentation
{
public class MyInstanceContextInitializer : IInstanceContextInitializer
{
public void Initialize(InstanceContext instanceContext, Message message)
{
MyInstanceContextExtension extension = new MyInstanceContextExtension();
//Add your custom InstanceContext extension that will let you associate state with this instancecontext
instanceContext.Extensions.Add(extension);
}
}
//Create an Extension that will attach to each InstanceContext and let it retrieve the Id or whatever state you want to associate
public class MyInstanceContextExtension : IExtension<InstanceContext>
{
//Associate an Id with each Instance Created.
string _instanceId;
public MyInstanceContextExtension()
{ _instanceId = Guid.NewGuid().ToString(); }
public string InstanceId => _instanceId;
public void Attach(InstanceContext owner)
{
Console.WriteLine("Attached to new InstanceContext.");
}
public void Detach(InstanceContext owner)
{
Console.WriteLine("Detached from InstanceContext.");
}
}
public class InstanceInitializerBehavior : IEndpointBehavior
{
public void AddBindingParameters(ServiceEndpoint serviceEndpoint, BindingParameterCollection bindingParameters)
{ }
//Apply the custom IInstanceContextProvider to the EndpointDispatcher.DispatchRuntime
public void ApplyDispatchBehavior(ServiceEndpoint serviceEndpoint, EndpointDispatcher endpointDispatcher)
{
MyInstanceContextInitializer extension = new MyInstanceContextInitializer();
endpointDispatcher.DispatchRuntime.InstanceContextInitializers.Add(extension);
}
public void ApplyClientBehavior(ServiceEndpoint serviceEndpoint, ClientRuntime behavior)
{ }
public void Validate(ServiceEndpoint endpoint)
{ }
}
public class InstanceInitializerBehaviorExtensionElement : BehaviorExtensionElement
{
public override Type BehaviorType
{
get { return typeof(InstanceInitializerBehavior); }
}
protected override object CreateBehavior()
{
return new InstanceInitializerBehavior();
}
}
}