Genişletilebilen 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> Deseni

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 toplama bildirimi sağlayın.

Uygulamaların bir sahipten eklenip kaldırılma zamanlarını kısıtlaması için geçerlidir. Örneğin, sahip veya uzantı belirli bir durumdayken uzantıların eklenmesine veya kaldırılmasına izin vermez, aynı anda birden çok sahipe eklemeye izin vermez veya yalnızca tek bir eklemeye ve ardından tek bir kaldırmaya izin vererek kaldırmaya izin veremiyebilirsiniz.

IExtension<T> diğer standart yönetilen arabirimlerle herhangi bir etkileşim anlamına gelmez. Özellikle, IDisposable.Dispose sahip nesnedeki 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 ile Detacharasındayken Attach koleksiyonda bulunmasına güvenebileceği anlamına gelir.

nesnesine FindAll geçirildi veya Find olması IExtension<T> gerekmiyor (örneğin, herhangi bir nesneyi geçirebilirsiniz), ancak döndürülen uzantı bir IExtension<T>olur.

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, türü kullanarak başka bir bileşenin Extensions arama yapmasını sağlamak üzere bir nesneye durum eklemek için tür tabanlı sözlük olarak özelliği kullanılır.

İkinci senaryo, bir nesnenin Attach olaylara kaydolma, durum geçişlerini izleme gibi özel davranışlara katılmasını sağlamak için ve Detach özelliklerini kullanır.

IExtensionCollection<T> Arabirimi, türüne IExtension<T> göre öğesinin alınmasına IExtension<T> izin veren nesnelerin koleksiyonudur. IExtensionCollection<T>.Find , bu türdeki IExtension<T> en son eklenen 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 konağı için temel sınıftı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ği hakkındaki bilgilerin yanı sıra öğesini içeren ServiceHostBase'lere InstanceContextbaşvuru içerir. Bu sınıfın uzantıları, veya davranışını InstanceContext 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ı, her işlem için davranışını OperationContext genişletebilir veya 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ı, davranışını IClientChannel genişletebilir veya her kanalın durumunu depolamak için 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.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Configuration;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Description;
using System.Text;

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()
    { this.instanceId = Guid.NewGuid().ToString(); }

    public String InstanceId
    {
      get
      { return this.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 bkz.