Aracılığıyla paylaş


Genişletilebilir Nesneler

Genişletilebilir nesne deseni, var olan çalışma zamanı sınıflarını yeni işlevsellikle genişletmek veya bir nesneye yeni durum eklemek için kullanılır. Genişletilebilir nesnelerden birine bağlı uzantılar, paylaşılan duruma ve erişebilecekleri ortak bir genişletilebilir nesneye bağlı işlevlere erişmek için işlemenin çok farklı aşamalarında davranışları etkinleştirir.

IExtensibleObject<T> Örüntüsü

Genişletilebilir nesne deseninde üç arabirim vardır: IExtensibleObject<T>, IExtension<T>ve IExtensionCollection<T>.

Arabirim IExtensibleObject<T> , nesnelerin işlevlerini özelleştirmesine izin veren IExtension<T> türler tarafından uygulanır.

Genişletilebilir nesneler, nesnelerin dinamik olarak toplanmalarını IExtension<T> sağlar. IExtension<T> nesneleri aşağıdaki arabirimle karakterize edilir:

public interface IExtension<T>
where T : IExtensibleObject<T>
{
    void Attach(T owner);
    void Detach(T owner);
}

Tür kısıtlaması, uzantıların yalnızca olan sınıflar için tanımlanabileceğini garanti eder IExtensibleObject<T>. Attach ve Detach toplama veya dağıtma bildirimi sağlar.

Bir sahibe eklenip kaldırılabilecekleri zamanı kısıtlamak uygulamalar için geçerlidir. Örneğin, tamamen kaldırılmasına izin vermeyerek, sahip veya uzantı belirli bir durumdayken uzantı ekleme veya kaldırmaya izin vermeyerek, aynı anda birden fazla sahipe eklenmeye izin vermeyerek veya yalnızca tek bir eklemenin ardından tek bir kaldırmaya izin vererek yönetebilirsiniz.

IExtension<T> diğer standart yönetilen arabirimlerle herhangi bir etkileşim anlamına gelmez. Sahip olan nesne üzerindeki IDisposable.Dispose yöntemi, normalde uzantılarını ayırmaz.

Bir uzantı koleksiyona eklendiğinde, Attach koleksiyona girmeden önce çağrılır. Bir uzantı koleksiyondan kaldırıldığında, Detach kaldırıldıktan sonra çağrılır. Bu, bir uzantının (uygun eşitleme varsayılarak) yalnızca Attach ile Detach arasında olduğunda koleksiyonda bulunmasına güvenebileceği anlamına gelir.

Geçirilen nesne olarak FindAll veya Find olmasına gerek yoktur (örneğin, herhangi bir nesneyi geçirebilirsiniz), ancak geri döndürülen uzantı bir IExtension<T>'dir.

Koleksiyonda IExtension<T>Find uzantı yoksa null döndürür ve FindAll boş bir koleksiyon döndürür. Birden çok uzantı uygularsa IExtension<T>, Find bunlardan birini döndürür. 'den FindAll döndürülen değer bir anlık görüntüdür.

İki ana senaryo vardır. İlk senaryoda, başka bir bileşenin tür kullanarak arama yapabilmesi için bir öğeye durum eklemek amacıyla Extensions özelliği tür tabanlı sözlük olarak kullanılır.

İkinci senaryoda, bir nesnenin etkinliklere kaydolma, durum geçişlerini izleme gibi özel davranışlarda bulunmasını sağlamak için Attach ve Detach özellikleri kullanılır.

IExtensionCollection<T> Arabirimi, türüne göre IExtension<T> öğesine erişilmesini sağlayan IExtension<T> nesnelerden oluşan bir koleksiyondur. IExtensionCollection<T>.Find, o türdeki en son eklenen IExtension<T> nesneyi döndürür.

Windows Communication Foundation'da Genişletilebilir Nesneler

Windows Communication Foundation'da (WCF) dört genişletilebilir nesne vardır:

  • ServiceHostBase – Bu, hizmetin ana bilgisayar için temel sınıfıdır. Bu sınıfın uzantıları, kendi davranışını ServiceHostBase genişletmek veya her hizmetin durumunu depolamak için kullanılabilir.

  • InstanceContext – Bu sınıf, hizmet türünün bir örneğini hizmet çalışma zamanına bağlar. Örneğe dair bilgilerin yanı sıra, InstanceContext'yi içeren ServiceHostBase'ye referans da içerir. Bu sınıfın uzantıları, InstanceContext davranışını genişletmek veya her hizmetin durumunu depolamak için kullanılabilir.

  • OperationContext – Bu sınıf, çalışma zamanının her işlem için topladığı işlem bilgilerini temsil eder. Bu, gelen ileti üst bilgileri, gelen ileti özellikleri, gelen güvenlik kimliği ve diğer bilgiler gibi bilgileri içerir. Bu sınıfın uzantıları ya OperationContext davranışını genişletebilir ya da her işlem için durumu depolayabilir.

  • IContextChannel – Bu arabirim, WCF çalışma zamanı tarafından oluşturulan kanallar ve proxy'ler için her durumun denetlenmesini sağlar. Bu sınıfın uzantıları, IClientChannel'ün davranışlarını genişletebilir ya da her kanalın durumunu depolamak amacıyla kullanabilir.

Aşağıdaki kod örneği, nesneleri izlemek InstanceContext için basit bir uzantının kullanımını gösterir.

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();
        }
    }
}

Ayrıca bakınız