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 için Windows Communication Foundation (WCF) çalışma zamanını özelleştirmeyi 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ş sepetini ziyaret ettiğimizde özgün 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 dayanıklı bir depolama medyasına kalıcı hale getirerek 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 örneğin varsayılan durumu vardır. 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 karşıtlık mantığını uygulamak için hizmet 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ğini yazmalı ve hizmetten bu bağlam kimliğini iletilerden okumalı ve üst düzeylere geçirmelidir. 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 IContextManager veya iletiden bağlam kimliğini yazmak ve okumak için uygulamaları 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 .
GetContextId Bu sınıftaki yöntemi, istemciden bağlam kimliğinin kaynağı olarak 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 tanımlama bilgisi ü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, sınıfı bunu yöntemindeki MessageHeaderContextManager bir SOAP üst bilgisine WriteContext 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 Hem hem de ReadContextId sınıfındaki DurableInstanceContextChannelBase yöntemleri sırasıyla ve IContextManager.ReadContext'yi IContextManager.WriteContext çağırır. Ancak, bu bağlam yöneticileri doğrudan sınıfı tarafından DurableInstanceContextChannelBase oluşturulmaz. Bunun yerine bu işi yapmak için sınıfını ContextManagerFactory 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 sınıfı koleksiyonuna Properties eklerMessage. Ayrıca bağlam kimliğinin okunamaması durumunda bir oluşturur CommunicationException ve bu nedenle kanalın durdurulmasına neden olur.
message.Properties.Add(DurableInstanceContextUtility.ContextIdProperty, contextId);
Devam etmeden önce, sınıfındaki Properties koleksiyonun Message 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ı bağlam kimliğini SOAP üst bilgisi veya HTTP tanımlama bilgisi ü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.
Şimdi sınıfıyla DurableInstanceContextChannelBase birlikte gerekli arabirimlerin onunu da (IOutputChannel, IInputChannel, IOutputSessionChannel, IInputSessionChannel, IRequestChannel, IReplyChannel, IRequestSessionChannel, IReplySessionChannel, IDuplexChannel, IDuplexSessionChannel) uygulanmalıdır. Kullanılabilir her ileti değişimi desenini (veri birimi, simpleks, çift yönlü ve oturum açma değişkenlerini) andırır. Bu uygulamaların her biri daha önce açıklanan temel sınıfı devralır ve uygun şekilde çağırır ApplyContextReadContextId . Örneğin, DurableInstanceContextOutputChannel - IOutputChannel arabirimini uygulayan - iletileri gönderen her yöntemden yöntemini çağırır ApplyContext .
public void Send(Message message, TimeSpan timeout)
{
// Apply the context information before sending the message.
this.ApplyContext(message);
//…
}
Öte yandan, DurableInstanceContextInputChannel arabirimini IInputChannel uygulayan - her yöntemde yöntemini çağırır ReadContextId ve bu da iletileri alı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 oturumun oluşturulmasına neden olan ilk ileti için salt okunur olduğundan emin olmak için temel bir mantığa sahiptir.
if (isFirstMessage)
{
//…
this.ApplyContext(message);
isFirstMessage = false;
}
Bu kanal uygulamaları daha sonra uygun şekilde sınıf ve DurableInstanceContextBindingElement sınıf tarafından WCF kanalı çalışma zamanına DurableInstanceContextBindingElementSection 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();
}
}
}
yönteminde GetInstance , belirli bir bağlam kimliği için serileştirilmiş veriler okunur ve ondan oluşturulur nesnesi ç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 örneklemesi gerekmez. Depolama yöneticisi oluşturma ayrıntılarından soyutlanan sınıfını kullanırlar StorageManagerFactory . 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 arabirimi uyguladığından emin olmak için verilen türü doğrular IStorageManager .
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> arabirimi, IExtensions'ın türüne göre alınmasına 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. döndürürse null, hizmet türünün yeni bir örneği oluşturulur ve çağırana 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.
ApplyDispatchBehavior Uygulamada geçerli InstanceContextModeServiceBehavior özniteliğin doğrulanıyor. 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 örnekleri, örnek bağlam başlatıcısı ve örnek sağlayıcısı her uç nokta için oluşturulan içinde DispatchRuntime oluşturulur ve 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 protokolunu etkinleştiren bir kanal oluşturmş ve ayrıca örnekleri kalıcı depolamadan yüklemek için varsayılan saklama davranışının üzerine yazmıştır.
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 yöntem oluşturulurken ApplyBehavior WCF çalışma zamanı yöntemini çağırırDispatchOperation. 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ı, için oluşturulan varsayılan işlem çağırıcısı için sarmalayıcıdırDispatchOperation. 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ısına temsilci olarak atandı. 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. Örneğin birden çok çalıştırması arası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.