Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Dayanıklı örnek, dayanıklı örnek bağlamlarını etkinleştirmek amacıyla Windows Communication Foundation (WCF) çalışma zamanının nasıl özelleştirileceğini gösterir. Destek deposu olarak SQL Server 2005 kullanır (bu örnekte SQL Server 2005 Express). Ancak, özel depolama mekanizmalarına erişmenin bir yolunu da sağlar.
Not
Bu örnek için kurulum yordamı ve derleme yönergeleri bu makalenin sonunda bulunur.
Bu örnek, WCF'nin hem kanal katmanını hem de hizmet modeli katmanını genişletmeyi içerir. Bu nedenle, uygulama ayrıntılarına geçmeden önce temel kavramları anlamak gerekir.
Dayanıklı örnek bağlamları gerçek dünya senaryolarında oldukça sık bulunabilir. Örneğin bir alışveriş sepeti uygulaması, alışverişi yarıya kadar duraklatma ve başka bir günde devam etme özelliğine sahiptir. Böylece ertesi gün alışveriş sepetine girdiğimizde orijinal bağlamımız geri yüklenir. Bağlantımız kesilirken alışveriş sepeti uygulamasının (sunucuda) alışveriş sepeti örneğini korumadığını unutmayın. Bunun yerine, durumunu kalıcı bir depolama ortamında saklar ve geri yüklenen bağlam için yeni bir örnek oluştururken kullanır. Bu nedenle, aynı bağlam için hizmet veren hizmet örneği önceki örnekle aynı değildir (yani, aynı bellek adresine sahip değildir).
Dayanıklı örnek bağlamı, istemci ve hizmet arasında bağlam kimliği alışverişi yapan küçük bir protokolle mümkün hale getirilmiştir. Bu bağlam kimliği istemcide oluşturulur ve hizmete iletilir. Hizmet örneği oluşturulduğunda, hizmet çalışma zamanı bu bağlam kimliğine karşılık gelen kalıcı durumu kalıcı bir depolama alanından yüklemeye çalışır (varsayılan olarak bir SQL Server 2005 veritabanıdır). Kullanılabilir durum yoksa, yeni örnek varsayılan durumuna sahip olur. Hizmet uygulaması, çalışma zamanının hizmet örneğini çağırdıktan sonra kaydedebilmesi için hizmet uygulamasının durumunu değiştiren işlemleri işaretlemek için özel bir öznitelik kullanır.
Önceki açıklamaya göre, hedefe ulaşmak için iki adım kolayca ayırt edilebilir:
- Bağlam kimliğini taşımak için kablo üzerinde giden iletiyi değiştirin.
- Özel örnekleme mantığını uygulamak için hizmetin yerel davranışını değiştirin.
Listedeki ilk ileti kablodaki iletileri etkilediğinden, özel bir kanal olarak uygulanmalı ve kanal katmanına bağlanmalıdır. İkincisi yalnızca hizmet yerel davranışını etkiler ve bu nedenle çeşitli hizmet genişletilebilirlik noktaları genişletilerek uygulanabilir. Sonraki birkaç bölümde bu uzantıların her biri ele alınıyor.
Dayanıklı InstanceContext Kanalı
İlk olarak bir kanal katmanı uzantısına bakılması gerekir. Özel kanal yazmanın ilk adımı, kanalın iletişim yapısına karar vermektir. Yeni bir kablo protokolü kullanıma sunulduğundan kanal, kanal yığınındaki hemen hemen tüm kanallarla çalışmalıdır. Bu nedenle tüm ileti değişimi desenlerini desteklemelidir. Ancak, iletişim yapısı ne olursa olsun kanalın temel işlevselliği aynıdır. Daha açık belirtmek gerekirse, istemciden iletilere bağlam kimliği numarasını yazmalı ve hizmetten bu bağlam kimliği numarasını iletilerden okuyup üst düzeylere iletmelidir. Bu nedenle, tüm dayanıklı örnek bağlam kanalı uygulamaları için soyut temel sınıf işlevi gören bir DurableInstanceContextChannelBase sınıf oluşturulur. Bu sınıf, iletilerde ve iletilerden bağlam bilgilerini uygulamak ve okumak için ortak durum makine yönetimi işlevlerini ve iki korumalı üyeyi içerir.
class DurableInstanceContextChannelBase
{
//…
protected void ApplyContext(Message message)
{
//…
}
protected string ReadContextId(Message message)
{
//…
}
}
Bu iki yöntem, iletiye veya iletiden bağlam kimliğini yazmak ve okumak için IContextManager uygulamalarını kullanır. (IContextManager tüm bağlam yöneticileri için sözleşmeyi tanımlamak için kullanılan özel bir arabirimdir.) Kanal, bağlam kimliğini özel soap üst bilgisine veya HTTP tanımlama bilgisi üst bilgisine ekleyebilir. Her bağlam yöneticisi uygulaması, tüm bağlam yöneticileri için ortak işlevselliği içeren sınıfından devralır ContextManagerBase . Bu sınıftaki GetContextId yöntemi, istemciden bağlam kimliğini başlatmak için kullanılır. Bağlam kimliği ilk kez başlatıldığında, bu yöntem bunu uzak uç nokta adresi tarafından oluşturulmuş bir metin dosyasına kaydeder (tipik URI'lerdeki geçersiz dosya adı karakterleri @ karakterleriyle değiştirilir).
Daha sonra aynı uzak uç nokta için bağlam kimliği gerekli olduğunda, uygun bir dosyanın var olup olmadığını denetler. Bunu yaparsa bağlam kimliğini okur ve döndürür. Aksi takdirde yeni oluşturulan bağlam kimliğini döndürür ve bir dosyaya kaydeder. Varsayılan yapılandırmayla, bu dosyalar geçerli kullanıcının geçici dizininde bulunan ContextStore adlı bir dizine yerleştirilir. Ancak bu konum bağlama öğesi kullanılarak yapılandırılabilir.
Bağlam kimliğini taşımak için kullanılan mekanizma yapılandırılabilir. HTTP çerez üst bilgisine veya özel bir SOAP üst bilgisine yazılabilir. Özel SOAP üst bilgisi yaklaşımı, bu protokolü HTTP olmayan protokollerle (örneğin, TCP veya Adlandırılmış Kanallar) kullanmayı mümkün kılar. Bu iki seçeneği uygulayan ve MessageHeaderContextManageradlı HttpCookieContextManager iki sınıf vardır.
her ikisi de iletiye uygun şekilde bağlam kimliğini yazar. Örneğin, MessageHeaderContextManager sınıfı, WriteContext yönteminde bunu bir SOAP üst bilgisine yazar.
public override void WriteContext(Message message)
{
string contextId = this.GetContextId();
MessageHeader contextHeader =
MessageHeader.CreateHeader(DurableInstanceContextUtility.HeaderName,
DurableInstanceContextUtility.HeaderNamespace,
contextId,
true);
message.Headers.Add(contextHeader);
}
ApplyContext ve ReadContextId, DurableInstanceContextChannelBase sınıfındaki yöntemler olarak sırasıyla IContextManager.ReadContext ve IContextManager.WriteContext'yi çağırır. Ancak, bu bağlam yöneticileri sınıf tarafından doğrudan oluşturulmaz. Bunun yerine, bu işi yapmak için ContextManagerFactory sınıfını kullanır.
IContextManager contextManager =
ContextManagerFactory.CreateContextManager(contextType,
this.contextStoreLocation,
this.endpointAddress);
ApplyContext yöntemi, gönderen kanallar tarafından çağrılır. Giden iletilere bağlam kimliğini ekler.
ReadContextId yöntemi, alıcı kanallar tarafından çağrılır. Bu yöntem, gelen iletilerde bağlam kimliğinin kullanılabilir olmasını sağlar ve Message sınıfının Properties koleksiyonuna kimliği ekler. Ayrıca, bağlam kimliğinin okunamaması durumunda bir hata CommunicationException atar ve bu nedenle kanalın durdurulmasına neden olur.
message.Properties.Add(DurableInstanceContextUtility.ContextIdProperty, contextId);
Devam etmeden önce, Properties koleksiyonunun Message sınıfındaki kullanımını anlamak önemlidir. Genellikle bu Properties koleksiyon, kanal katmanından alt düzeylerden üst düzeylere veri geçirilirken kullanılır. Bu şekilde, protokol ayrıntıları ne olursa olsun istenen veriler tutarlı bir şekilde üst düzeylere sağlanabilir. Başka bir deyişle, kanal katmanı context ID'yi SOAP üst bilgisi veya HTTP çerez üst bilgisi olarak gönderip alabilir. Ancak, kanal katmanı bu bilgileri koleksiyonda kullanılabilir hale getirdiğinden, üst düzeylerin Properties bu ayrıntıları bilmesi gerekmez.
DurableInstanceContextChannelBase sınıfı olarak, gerekli olan on arabirimin (IOutputChannel, IInputChannel, IOutputSessionChannel, IInputSessionChannel, IRequestChannel, IReplyChannel, IRequestSessionChannel, IReplySessionChannel, IDuplexChannel, IDuplexSessionChannel) uygulanması gerekmektedir. Mevcut her mesaj alışverişi modelini (datagram, simplex, dupleks ve oturumlu varyantlarını) temsil eder. Bu uygulamaların her biri daha önce açıklanan temel sınıfı devralır ve uygun şekilde çağırır ApplyContextReadContextId . Örneğin, IOutputChannel arabirimini uygulayan DurableInstanceContextOutputChannel, iletileri gönderen her yöntemden ApplyContext yöntemini çağırır.
public void Send(Message message, TimeSpan timeout)
{
// Apply the context information before sending the message.
this.ApplyContext(message);
//…
}
Öte yandan, DurableInstanceContextInputChannel arabirimini uygulayan IInputChannel, her bir yönteminde iletileri alan ReadContextId yöntemini çağırır.
public Message Receive(TimeSpan timeout)
{
//…
ReadContextId(message);
return message;
}
Bunun dışında, bu kanal uygulamaları yöntem çağrılarını kanal yığınında aşağıdaki kanala devreder. Ancak, oturumlu değişkenler, bağlam kimliğinin gönderildiğinden ve yalnızca oturumun oluşturulmasına neden olan ilk mesaj için okunduğundan emin olmak için temel bir mantığa sahiptir.
if (isFirstMessage)
{
//…
this.ApplyContext(message);
isFirstMessage = false;
}
Bu kanal uygulamaları daha sonra DurableInstanceContextBindingElement sınıfı ve DurableInstanceContextBindingElementSection sınıfı tarafından uygun şekilde WCF kanal çalışma zamanına eklenir.
Bağlama öğeleri ve bağlama öğesi bölümleri hakkında daha fazla bilgi için HttpCookieSession kanalı örnek belgelerine bakın.
Hizmet Modeli Katmanı Uzantıları
Bağlam kimliği kanal katmanı üzerinden geçtiğine göre, örnek oluşturma işlemini özelleştirmek için hizmet davranışı uygulanabilir. Bu örnekte, kalıcı depodan veya kalıcı depoya durum yüklemek ve kaydetmek için bir depolama yöneticisi kullanılır. Daha önce açıklandığı gibi bu örnek, destek deposu olarak SQL Server 2005 kullanan bir depolama yöneticisi sağlar. Ancak, bu uzantıya özel depolama mekanizmaları eklemek de mümkündür. Bunu yapmak için, tüm depolama yöneticileri tarafından uygulanması gereken bir genel arabirim bildirilir.
public interface IStorageManager
{
object GetInstance(string contextId, Type type);
void SaveInstance(string contextId, object state);
}
sınıfı varsayılan SqlServerStorageManagerIStorageManager uygulamayı içerir.
SaveInstance Yönteminde, verilen nesne XmlSerializer kullanılarak serileştirilir ve SQL Server veritabanına kaydedilir.
XmlSerializer serializer = new XmlSerializer(state.GetType());
string data;
using (StringWriter writer = new StringWriter(CultureInfo.InvariantCulture))
{
serializer.Serialize(writer, state);
data = writer.ToString();
}
using (SqlConnection connection = new SqlConnection(GetConnectionString()))
{
connection.Open();
string update = @"UPDATE Instances SET Instance = @instance WHERE ContextId = @contextId";
using (SqlCommand command = new SqlCommand(update, connection))
{
command.Parameters.Add("@instance", SqlDbType.VarChar, 2147483647).Value = data;
command.Parameters.Add("@contextId", SqlDbType.VarChar, 256).Value = contextId;
int rows = command.ExecuteNonQuery();
if (rows == 0)
{
string insert = @"INSERT INTO Instances(ContextId, Instance) VALUES(@contextId, @instance)";
command.CommandText = insert;
command.ExecuteNonQuery();
}
}
}
GetInstance yönteminde, belirli bir bağlam kimliği için serileştirilmiş veriler okunur ve ondan oluşturulan nesne çağırana döndürülür.
object data;
using (SqlConnection connection = new SqlConnection(GetConnectionString()))
{
connection.Open();
string select = "SELECT Instance FROM Instances WHERE ContextId = @contextId";
using (SqlCommand command = new SqlCommand(select, connection))
{
command.Parameters.Add("@contextId", SqlDbType.VarChar, 256).Value = contextId;
data = command.ExecuteScalar();
}
}
if (data != null)
{
XmlSerializer serializer = new XmlSerializer(type);
using (StringReader reader = new StringReader((string)data))
{
object instance = serializer.Deserialize(reader);
return instance;
}
}
Bu depolama yöneticilerinin kullanıcılarının bunları doğrudan örneklemesine izin verilmez.
StorageManagerFactory sınıfını, depolama yöneticisinin oluşturulma ayrıntılarından soyutlamak için kullanırlar. Bu sınıf, GetStorageManagerbelirli bir depolama yöneticisi türünün örneğini oluşturan bir statik üyesine sahiptir. tür parametresi ise null, bu yöntem varsayılan SqlServerStorageManager sınıfın bir örneğini oluşturur ve döndürür. Ayrıca, IStorageManager arayüzünü uyguladığından emin olmak için verilen türü doğrular.
public static IStorageManager GetStorageManager(Type storageManagerType)
{
IStorageManager storageManager = null;
if (storageManagerType == null)
{
return new SqlServerStorageManager();
}
else
{
object obj = Activator.CreateInstance(storageManagerType);
// Throw if the specified storage manager type does not
// implement IStorageManager.
if (obj is IStorageManager)
{
storageManager = (IStorageManager)obj;
}
else
{
throw new InvalidOperationException(
ResourceHelper.GetString("ExInvalidStorageManager"));
}
return storageManager;
}
}
Kalıcı depolamadan örnekleri okumak ve yazmak için gerekli altyapı uygulanır. Şimdi hizmet davranışını değiştirmek için gerekli adımlar atılmalıdır.
Bu işlemin ilk adımı olarak, kanal katmanından geçerli InstanceContext'e gelen bağlam kimliğini kaydetmemiz gerekir. InstanceContext, WCF dağıtıcısı ile hizmet örneği arasındaki bağlantı işlevi gören bir çalışma zamanı bileşenidir. Hizmet örneğine ek durum ve davranış sağlamak için kullanılabilir. Bu önemlidir çünkü oturumlu iletişimde bağlam kimliği yalnızca ilk iletiyle gönderilir.
WCF, genişletilebilir nesne desenini kullanarak yeni bir durum ve davranış ekleyerek InstanceContext çalışma zamanı bileşenini genişletmeye olanak tanır. Genişletilebilir nesne deseni WCF'de mevcut çalışma zamanı sınıflarını yeni işlevsellikle genişletmek veya bir nesneye yeni durum özellikleri eklemek için kullanılır. Genişletilebilir nesne deseninde üç arabirim vardır: IExtensibleObject<T>, IExtension<T> ve IExtensionCollection<T>:
IExtensibleObject<T> arabirimi, işlevlerini özelleştiren uzantılara izin veren nesneler tarafından uygulanır.
IExtension<T> arabirimi, T türündeki sınıfların uzantıları olan nesneler tarafından uygulanır.
IExtensionCollection<T> arayüzü, IExtensions'ın türüne göre alınabilmesine olanak tanıyan bir IExtensions koleksiyonudur.
Bu nedenle, IExtension arabirimini uygulayan ve bağlam kimliğini kaydetmek için gerekli durumu tanımlayan bir InstanceContextExtension sınıfı oluşturulmalıdır. Bu sınıf, kullanılmakta olan depolama yöneticisini tutma durumunu da sağlar. Yeni durum kaydedildikten sonra değiştirilmesi mümkün olmamalıdır. Bu nedenle, durum oluşturulurken sağlanıp örneğe kaydedilir ve ardından yalnızca salt okunur özellikler kullanılarak erişilebilir.
// Constructor
public DurableInstanceContextExtension(string contextId,
IStorageManager storageManager)
{
this.contextId = contextId;
this.storageManager = storageManager;
}
// Read only properties
public string ContextId
{
get { return this.contextId; }
}
public IStorageManager StorageManager
{
get { return this.storageManager; }
}
InstanceContextInitializer sınıfı IInstanceContextInitializer arabirimini uygular ve örnek bağlam uzantısını, oluşturulmuş InstanceContext'in Extensions koleksiyonuna ekler.
public void Initialize(InstanceContext instanceContext, Message message)
{
string contextId =
(string)message.Properties[DurableInstanceContextUtility.ContextIdProperty];
DurableInstanceContextExtension extension =
new DurableInstanceContextExtension(contextId,
storageManager);
instanceContext.Extensions.Add(extension);
}
Daha önce açıklandığı gibi bağlam kimliği sınıfın PropertiesMessage koleksiyonundan okunur ve uzantı sınıfının oluşturucusna geçirilir. Bu, bilgilerin tutarlı bir şekilde katmanlar arasında nasıl değiş tokuş edilebileceğini gösterir.
Sonraki önemli adım, hizmet örneği oluşturma işlemini geçersiz kılmadır. WCF, özel örnekleme davranışları uygulamaya ve bunları IInstanceProvider arabirimini kullanarak çalışma zamanına bağlamaya olanak tanır. Yeni InstanceProvider sınıf, bu işi yapmak için uygulanır. Örnek sağlayıcısından beklenen hizmet türü oluşturucuda kabul edilir. Daha sonra bu, yeni örnekler oluşturmak için kullanılır.
GetInstance Uygulamada, kalıcı bir örneği arayan bir depolama yöneticisi örneği oluşturulur. Eğer null döndürülürse, hizmet türünün yeni bir örneği oluşturulur ve çağırana geri döndürülür.
public object GetInstance(InstanceContext instanceContext, Message message)
{
object instance = null;
DurableInstanceContextExtension extension =
instanceContext.Extensions.Find<DurableInstanceContextExtension>();
string contextId = extension.ContextId;
IStorageManager storageManager = extension.StorageManager;
instance = storageManager.GetInstance(contextId, serviceType);
instance ??= Activator.CreateInstance(serviceType);
return instance;
}
Sonraki önemli adım, , InstanceContextExtensionve InstanceContextInitializer sınıflarını hizmet modeli çalışma zamanına yüklemektirInstanceProvider. Davranışı yüklemek üzere hizmet uygulama sınıflarını işaretlemek için özel bir öznitelik kullanılabilir.
DurableInstanceContextAttribute, bu özniteliğin uygulamasını içerir ve tüm hizmet çalışma zamanını genişletmek için arabirimini uygularIServiceBehavior.
Bu sınıf, kullanılacak depolama yöneticisinin türünü kabul eden bir özelliğe sahiptir. Bu şekilde, uygulama kullanıcıların kendi IStorageManager uygulamalarını bu özniteliğin parametresi olarak belirtmesine olanak tanır.
Geçerli InstanceContextModeServiceBehavior özniteliğin ApplyDispatchBehavior uygulamada doğrulanmaktadır. Bu özellik Singleton olarak ayarlanırsa, dayanıklı depolamayı etkinleştirmek mümkün değildir ve konağı bilgilendirmek için bir InvalidOperationException oluşturulur.
ServiceBehaviorAttribute serviceBehavior =
serviceDescription.Behaviors.Find<ServiceBehaviorAttribute>();
if (serviceBehavior != null &&
serviceBehavior.InstanceContextMode == InstanceContextMode.Single)
{
throw new InvalidOperationException(
ResourceHelper.GetString("ExSingletonInstancingNotSupported"));
}
Bundan sonra depolama yöneticisinin, örnek bağlam başlatıcısının ve örnek sağlayıcısının örnekleri oluşturulur ve her uç nokta için oluşturulan DispatchRuntime'e yüklenir.
IStorageManager storageManager =
StorageManagerFactory.GetStorageManager(storageManagerType);
InstanceContextInitializer contextInitializer =
new InstanceContextInitializer(storageManager);
InstanceProvider instanceProvider =
new InstanceProvider(description.ServiceType);
foreach (ChannelDispatcherBase cdb in serviceHostBase.ChannelDispatchers)
{
ChannelDispatcher cd = cdb as ChannelDispatcher;
if (cd != null)
{
foreach (EndpointDispatcher ed in cd.Endpoints)
{
ed.DispatchRuntime.InstanceContextInitializers.Add(contextInitializer);
ed.DispatchRuntime.InstanceProvider = instanceProvider;
}
}
}
Özetle, bu örnek, özel bağlam kimliği değişimi için özel kablo protokolünü etkinleştiren bir kanal oluşturmuştur ve ayrıca örnekleri kalıcı depolamadan yüklemek için varsayılan örnekleme davranışını değiştirmiştir.
Kalan, hizmet örneğini kalıcı depolama alanına kaydetmenin bir yoludur. Daha önce açıklandığı gibi, bir IStorageManager uygulamada durumu kaydetmek için gerekli işlevler zaten vardır. Şimdi bunu WCF çalışma zamanıyla tümleştirmemiz gerekir. Hizmet uygulama sınıfındaki yöntemler için geçerli olan başka bir öznitelik gereklidir. Bu özniteliğin hizmet örneğinin durumunu değiştiren yöntemlere uygulanması gerekir.
SaveStateAttribute sınıfı bu işlevi uygular. Ayrıca her işlem için WCF çalışma zamanını değiştirmek için sınıfını uygular IOperationBehavior . Bir yöntem bu öznitelikle işaretlendiğinde, uygun DispatchOperation oluşturulurken WCF çalışma zamanı ApplyBehavior yöntemini çağırır. Bu yöntem uygulamasında tek bir kod satırı vardır:
dispatch.Invoker = new OperationInvoker(dispatch.Invoker);
Bu yönerge türün OperationInvoker bir örneğini oluşturur ve oluşturulan Invoker özelliğine DispatchOperation atar.
OperationInvoker sınıfı, DispatchOperation için oluşturulan varsayılan işlem çağırıcısının bir sarmalayıcıdır. Bu sınıf arabirimini IOperationInvoker uygular.
Invoke Yöntem uygulamasında, gerçek yöntem çağrısı iç işlem çağırıcıya devredilir. Ancak sonuçları döndürmeden önce içindeki depolama yöneticisi InstanceContext hizmet örneğini kaydetmek için kullanılır.
object result = innerOperationInvoker.Invoke(instance,
inputs, out outputs);
// Save the instance using the storage manager saved in the
// current InstanceContext.
InstanceContextExtension extension =
OperationContext.Current.InstanceContext.Extensions.Find<InstanceContextExtension>();
extension.StorageManager.SaveInstance(extension.ContextId, instance);
return result;
Uzantıyı Kullanma
Hem kanal katmanı hem de hizmet modeli katmanı uzantıları yapılır ve bunlar artık WCF uygulamalarında kullanılabilir. Hizmetler, özel bir bağlama kullanarak kanalı kanal yığınına eklemeli ve ardından hizmet uygulama sınıflarını uygun özniteliklerle işaretlemelidir.
[DurableInstanceContext]
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
public class ShoppingCart : IShoppingCart
{
//…
[SaveState]
public int AddItem(string item)
{
//…
}
//…
}
İstemci uygulamalarının özel bağlama kullanarak DurableInstanceContextChannel'i kanal yığınına eklemesi gerekir. Yapılandırma dosyasında kanalı bildirimli olarak yapılandırmak için bağlama öğesi bölümünün bağlama öğesi uzantıları koleksiyonuna eklenmesi gerekir.
<system.serviceModel>
<extensions>
<bindingElementExtensions>
<add name="durableInstanceContext"
type="Microsoft.ServiceModel.Samples.DurableInstanceContextBindingElementSection, DurableInstanceContextExtension, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</bindingElementExtensions>
</extensions>
</system.serviceModel>
Artık bağlama öğesi, diğer standart bağlama öğeleri gibi özel bağlama ile kullanılabilir:
<bindings>
<customBinding>
<binding name="TextOverHttp">
<durableInstanceContext contextType="HttpCookie"/>
<reliableSession />
<textMessageEncoding />
<httpTransport />
</binding>
</customBinding>
</bindings>
Sonuç
Bu örnekte özel bir protokol kanalının nasıl oluşturulacağı ve hizmet davranışını etkinleştirecek şekilde nasıl özelleştirileceği gösterildi.
Uzantı, kullanıcıların bir yapılandırma bölümü kullanarak uygulamayı belirtmesine IStorageManager izin vererek daha da geliştirilebilir. Bu, hizmet kodunu yeniden derlemeden yedekleme deposunu değiştirmeyi mümkün kılar.
Ayrıca, örneğin durumunu kapsülleyen bir sınıf (örneğin, StateBag) uygulamayı deneyebilirsiniz. Bu sınıf, her değiştiğinde durumu kalıcı hale döndürmekle sorumludur. Bu şekilde özniteliğini SaveState kullanmaktan kaçınabilir ve kalıcı çalışmayı daha doğru bir şekilde gerçekleştirebilirsiniz (örneğin, özniteliğine sahip SaveState bir yöntem çağrıldığında her seferinde kaydetmek yerine durum gerçekten değiştiğinde durumu kalıcı hale getirebilirsiniz).
Örneği çalıştırdığınızda aşağıdaki çıkış görüntülenir. müşteri alışveriş sepetine iki öğe ekler ve ardından alışveriş sepetindeki öğelerin listesini hizmetten alır. Hizmeti ve istemciyi kapatmak için her konsol penceresinde ENTER tuşuna basın.
Enter the name of the product: apples
Enter the name of the product: bananas
Shopping cart currently contains the following items.
apples
bananas
Press ENTER to shut down client
Not
Hizmetin yeniden oluşturulması veritabanı dosyasının üzerine yazılır. Birden çok çalıştırma sırasında korunan durumu gözlemlemek için, çalıştırmalar arasında örneği yeniden oluşturmamaya dikkat edin.
Örneği ayarlamak, derlemek ve çalıştırmak için
Windows Communication Foundation Örnekleri için Tek Seferlik Kurulum Yordamı'nı gerçekleştirdiğinizden emin olun.
Çözümü oluşturmak için Windows Communication Foundation Örnekleri Oluşturma başlığındaki yönergeleri izleyin.
Örneği tek veya makineler arası bir yapılandırmada çalıştırmak için Windows Communication Foundation Örneklerini Çalıştırma başlığındaki yönergeleri izleyin.
Not
Bu örneği çalıştırmak için SQL Server 2005 veya SQL Express 2005 çalıştırıyor olmanız gerekir. SQL Server 2005 çalıştırıyorsanız, hizmetin bağlantı dizesi yapılandırmasını değiştirmeniz gerekir. Çapraz makine çalıştırılırken SQL Server yalnızca sunucu makinesinde gereklidir.