Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Rozszerzalny wzorzec obiektu służy do rozszerzania istniejących klas środowiska uruchomieniowego o nowe funkcje lub dodawania nowego stanu do obiektu. Rozszerzenia, dołączone do jednego z rozszerzalnych obiektów, umożliwiają zachowanie na bardzo różnych etapach przetwarzania w celu uzyskania dostępu do stanu udostępnionego i funkcji dołączonych do wspólnego rozszerzalnego obiektu, do którego mogą uzyskiwać dostęp.
Wzorzec IExtensibleObject<T>
Istnieją trzy interfejsy w rozszerzalnym wzorcu obiektu: IExtensibleObject<T>, IExtension<T>i IExtensionCollection<T>.
Interfejs IExtensibleObject<T> jest implementowany przez typy, które umożliwiają IExtension<T> obiektom dostosowywanie ich funkcjonalności.
Rozszerzalne obiekty umożliwiają dynamiczną IExtension<T> agregację obiektów. IExtension<T> obiekty charakteryzują się następującym interfejsem:
public interface IExtension<T>
where T : IExtensibleObject<T>
{
void Attach(T owner);
void Detach(T owner);
}
Ograniczenie typu gwarantuje, że rozszerzenia można zdefiniować tylko dla klas, które są IExtensibleObject<T>. Attach i Detach podaj powiadomienie o agregacji lub dezagregacji.
Implementacje mogą zgodnie z zasadami ograniczać czas, w którym mogą być dodawane i usuwane od właściciela. Na przykład możesz całkowicie uniemożliwić usunięcie, nie pozwalając na dodawanie lub usuwanie rozszerzeń, kiedy właściciel lub rozszerzenie są w określonym stanie; możesz także nie pozwalać na dodawanie do wielu właścicieli jednocześnie, lub zezwalać tylko na jedno dodanie, po którym następuje jedno usunięcie.
IExtension<T> nie oznacza żadnych interakcji z innymi standardowymi interfejsami zarządzanymi. Metoda IDisposable.Dispose obiektu właściciela w szczególności zwykle nie odłącza swoich rozszerzeń.
Kiedy rozszerzenie jest dodawane do kolekcji, Attach jest wywoływane zanim trafi do kolekcji. Gdy rozszerzenie zostanie usunięte z kolekcji, Detach jest wywoływane po jego usunięciu. Oznacza to ,że (przy założeniu odpowiedniej synchronizacji) rozszerzenie może liczyć tylko na to, że znajduje się w kolekcji, gdy znajduje się między Attach i Detach.
Obiekt przekazany do FindAll lub Find nie musi być IExtension<T> (na przykład można przekazać dowolny obiekt), ale zwrócone rozszerzenie jest rozszerzeniem typu IExtension<T>.
Jeśli w kolekcji nie ma rozszerzenia IExtension<T>, Find zwraca wartość null, a FindAll zwraca pustą kolekcję. Jeśli implementuje IExtension<T>się wiele rozszerzeń, Find zwraca jeden z nich. Wartość zwrócona z FindAll jest migawką.
Istnieją dwa główne scenariusze. Pierwszy scenariusz używa Extensions właściwości jako słownika opartego na typie, aby wstawić stan do obiektu, aby umożliwić innemu komponentowi odnalezienie go według typu.
W drugim scenariuszu użyto właściwości Attach i Detach, aby umożliwić obiektowi uczestniczenie w niestandardowym zachowaniu, takim jak rejestrowanie się na wydarzenia, monitorowanie przejść stanu itd.
Interfejs IExtensionCollection<T> jest kolekcją IExtension<T> obiektów, które umożliwiają pobieranie elementu IExtension<T> według jego typu. IExtensionCollection<T>.Find Zwraca ostatnio dodany obiekt, który jest IExtension<T> tego typu.
Rozszerzalne obiekty w programie Windows Communication Foundation
W programie Windows Communication Foundation (WCF) istnieją cztery rozszerzalne obiekty:
ServiceHostBase — jest to klasa bazowa hosta usługi. Rozszerzenia tej klasy mogą służyć do rozszerzania zachowania ServiceHostBase samego siebie lub przechowywania stanu dla każdej usługi.
InstanceContext — Ta klasa łączy wystąpienie typu usługi ze środowiskiem uruchomieniowym usługi. Zawiera informacje o wystąpieniu oraz odniesienie do elementu InstanceContext's zawierającego ServiceHostBase. Rozszerzenia tej klasy mogą służyć do rozszerzania zachowania InstanceContext klasy lub do przechowywania stanu dla każdej usługi.
OperationContext — Ta klasa reprezentuje informacje o operacji zbierane przez środowisko uruchomieniowe dla każdej operacji. Obejmuje to informacje, takie jak nagłówki komunikatów przychodzących, właściwości komunikatów przychodzących, tożsamość zabezpieczeń przychodzących i inne informacje. Rozszerzenia tej klasy mogą rozszerzać zachowanie OperationContext lub przechowywać stan dla każdej operacji.
IContextChannel — Ten interfejs umożliwia inspekcję każdego stanu kanałów i serwerów proxy utworzonych przez środowisko uruchomieniowe programu WCF. Rozszerzenia tej klasy mogą rozszerzyć zachowanie IClientChannel lub użyć ich do przechowywania stanu dla każdego kanału.
Poniższy przykład kodu przedstawia użycie prostego rozszerzenia do śledzenia InstanceContext obiektów.
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();
}
}
}