Megosztás:


Tartós példány környezete

A Durable minta bemutatja, hogyan szabhatja testre a Windows Communication Foundation (WCF) futtatókörnyezetet a tartós példánykörnyezetek engedélyezéséhez. Az SQL Server 2005-öt használja háttértárként (ebben az esetben az SQL Server 2005 Expresst). Emellett azonban lehetővé teszi az egyéni tárolási mechanizmusok elérését is.

Feljegyzés

A minta telepítési eljárása és összeállítási utasításai a cikk végén találhatók.

Ez a minta magában foglalja a WCF csatornarétegének és szolgáltatásmodell-rétegének kiterjesztését is. Ezért a megvalósítás részleteinek megismerése előtt tisztában kell lenni a mögöttes fogalmakkal.

A tartós példánykörnyezetek gyakran megtalálhatók a valós forgatókönyvekben. Egy bevásárlókocsi-alkalmazás például félúton szüneteltetheti a vásárlást, és folytathatja azt egy másik napon. Így amikor másnap meglátogatjuk a bevásárlókocsit, az eredeti környezetünk helyreáll. Fontos megjegyezni, hogy a bevásárlókocsi-alkalmazás (a kiszolgálón) nem tartja karban a bevásárlókocsi-példányt a leválasztott állapotban. Ehelyett megőrzi az állapotát egy tartós tároló adathordozón, és azt használja a visszaállított környezet új példányának létrehozásakor. Ezért a szolgáltatáspéldány, amely ugyanahhoz a környezethez használható, nem ugyanaz, mint az előző példány (vagyis nem ugyanaz a memóriacím).

A tartós példánykörnyezetet egy kis protokoll teszi lehetővé, amely egy környezeti azonosítót cserél az ügyfél és a szolgáltatás között. Ezt a környezeti azonosítót az ügyfél hozza létre, és továbbítja a szolgáltatásnak. A szolgáltatáspéldány létrehozásakor a szolgáltatás futtatókörnyezete egy állandó tárolóból próbálja betölteni a környezeti azonosítónak megfelelő állandó állapotot (alapértelmezés szerint SQL Server 2005-adatbázis). Ha nincs elérhető állapot, az új példány alapértelmezett állapota van. A szolgáltatás implementációja egy egyéni attribútummal jelöli meg a szolgáltatás-implementáció állapotát módosító műveleteket, hogy a futtatókörnyezet a meghívásuk után menthesse a szolgáltatáspéldányt.

Az előző leírás alapján két lépés könnyen megkülönböztethető a cél eléréséhez:

  1. Módosítsa a vezetéken lévő üzenetet a környezeti azonosító hordozásához.
  2. Módosítsa a szolgáltatás helyi viselkedését az egyéni instancing logika implementálásához.

Mivel a listában elsőként szereplő üzenet hatással van a vezetéken lévő üzenetekre, egyéni csatornaként kell megvalósítani, és a csatornaréteghez kell csatlakoztatni. Ez utóbbi csak a szolgáltatás helyi viselkedését befolyásolja, ezért több szolgáltatási bővíthetőségi pont kibővítésével valósítható meg. A következő néhány szakaszban ezeket a bővítményeket tárgyaljuk.

Tartós InstanceContext csatorna

Az első dolog, amit meg kell nézni, egy csatornaréteg-bővítmény. Az egyéni csatornák írásának első lépése a csatorna kommunikációs struktúrájának meghatározása. Az új vezetékes protokoll bevezetésekor a csatornának a csatorna verem szinte bármely más csatornájával együtt kell működnie. Ezért minden üzenetváltási mintát támogatnia kell. A csatorna alapvető funkciói azonban a kommunikációs struktúrától függetlenül azonosak. Pontosabban, az ügyfélnek meg kell írnia a környezeti azonosítót az üzenetekbe, és a szolgáltatásból be kell olvasnia ezt a környezeti azonosítót az üzenetekből, és át kell adnia a felső szinteknek. Emiatt létrejön egy DurableInstanceContextChannelBase osztály, amely az összes tartós példány környezeti csatorna implementációjának absztrakt alaposztálya. Ez az osztály tartalmazza a közös állapotgép-kezelési függvényeket és két védett tagot, amelyek a környezeti információkat az üzenetekre és az üzenetekből is alkalmazni és olvasni szeretnék.

class DurableInstanceContextChannelBase
{
  //…
  protected void ApplyContext(Message message)
  {
    //…
  }
  protected string ReadContextId(Message message)
  {
    //…
  }
}

Ez a két módszer IContextManager implementációkkal írja és olvassa be a környezet azonosítóját az üzenetbe vagy az üzenetből. (IContextManager egy egyéni felület, amely az összes környezetkezelő szerződésének meghatározására szolgál.) A csatorna tartalmazhatja a környezetazonosítót egy egyéni SOAP-fejlécben vagy egy HTTP-cookie-fejlécben. Minden környezetmenedzser-implementáció attól az ContextManagerBase osztálytól öröklődik, amely az összes környezetkezelő közös funkcióit tartalmazza. Az GetContextId ebben az osztályban található metódus az ügyfél környezeti azonosítójának származtatására szolgál. Amikor egy környezetazonosító első alkalommal származik, ez a metódus egy olyan szövegfájlba menti, amelynek a nevét a távoli végpont címe alkotja (a tipikus URI-k érvénytelen fájlnév karaktereit @ karakterekkel cseréli le).

Később, amikor ugyanahhoz a távoli végponthoz környezeti azonosítóra van szükség, ellenőrzi, hogy létezik-e megfelelő fájl. Ha igen, beolvassa a környezeti azonosítót, és visszaadja. Ellenkező esetben egy újonnan létrehozott környezeti azonosítót ad vissza, és menti egy fájlba. Az alapértelmezett konfigurációval ezek a fájlok egy ContextStore nevű könyvtárba kerülnek, amely az aktuális felhasználó ideiglenes könyvtárában található. Ez a hely azonban konfigurálható a kötési elem használatával.

A környezetazonosító átvitelére használt mechanizmus konfigurálható. A http-cookie-fejlécbe vagy egy egyéni SOAP-fejlécbe írható. Az egyéni SOAP-fejléc megközelítés lehetővé teszi, hogy ezt a protokollt nem HTTP protokollokkal (például TCP vagy Named Pipes) használja. Két osztály van, nevezetesen MessageHeaderContextManager és HttpCookieContextManager, amelyek implementálják ezt a két lehetőséget.

Mindkettő megfelelően írja be a környezeti azonosítót az üzenetbe. Az osztály például MessageHeaderContextManager egy SOAP fejlécbe írja a WriteContext metódusban.

public override void WriteContext(Message message)
{
  string contextId = this.GetContextId();

  MessageHeader contextHeader =
    MessageHeader.CreateHeader(DurableInstanceContextUtility.HeaderName,
      DurableInstanceContextUtility.HeaderNamespace,
      contextId,
      true);

  message.Headers.Add(contextHeader);
}

Az osztályban ApplyContext lévő metódusok és ReadContextId metódusok DurableInstanceContextChannelBase is meghívják az és IContextManager.ReadContexta IContextManager.WriteContext metódusokat. Ezeket a környezetkezelőket azonban nem közvetlenül az DurableInstanceContextChannelBase osztály hozza létre. Ehelyett az osztályt ContextManagerFactory használja a feladat elvégzéséhez.

IContextManager contextManager =
                ContextManagerFactory.CreateContextManager(contextType,
                this.contextStoreLocation,
                this.endpointAddress);

A ApplyContext metódust a küldő csatornák hívják meg. Beszúrja a környezeti azonosítót a kimenő üzenetekbe. A ReadContextId metódust a fogadó csatornák hívják meg. Ez a módszer biztosítja, hogy a környezeti azonosító elérhető legyen a bejövő üzenetekben, és hozzáadja azt az PropertiesMessage osztály gyűjteményéhez. Emellett a környezeti azonosító beolvasásának meghiúsulása esetén is hibát jelez CommunicationException , és így a csatorna megszakad.

message.Properties.Add(DurableInstanceContextUtility.ContextIdProperty, contextId);

A folytatás előtt fontos megérteni a gyűjtemény használatát Properties az Message osztályban. Ezt a gyűjteményt általában akkor Properties használják, ha a csatornaréteg alsó és felső szintjei között ad át adatokat. Így a kívánt adatok a protokoll részleteitől függetlenül konzisztens módon szolgáltathatók a felső szinteknek. Más szóval a csatornaréteg soap fejlécként vagy HTTP-cookie-fejlécként küldheti el és fogadhatja a környezeti azonosítót. A felső szinteknek azonban nem kell tudniuk ezekről a részletekről, mert a csatornaréteg elérhetővé teszi ezeket az információkat a Properties gyűjteményben.

Most az DurableInstanceContextChannelBase osztály helyén mind a tíz szükséges interfészt (IOutputChannel, IInputChannel, IOutputSessionChannel, IInputSessionChannel, IRequestChannel, IReplyChannel, IRequestSessionChannel, IReplySessionChannel, IDuplexChannel, IDuplexSessionChannel) végre kell hajtani. Minden elérhető üzenetváltási mintára (datagram, simplex, duplex és munkamenet-alapú változatokra) hasonlítanak. Ezen implementációk mindegyike örökli a korábban leírt alaposztályt, valamint a hívásokat ApplyContext és ReadContextId a megfelelő módon. Például DurableInstanceContextOutputChannel – amely az IOutputChannel felületet implementálja – meghívja a ApplyContext metódust az üzeneteket küldő metódusokból.

public void Send(Message message, TimeSpan timeout)
{
    // Apply the context information before sending the message.
    this.ApplyContext(message);
    //…
}

Másrészt DurableInstanceContextInputChannel - amely megvalósítja az IInputChannel interfészt - meghívja a ReadContextId metódust az egyes metódusokban, amelyek fogadják az üzeneteket.

public Message Receive(TimeSpan timeout)
{
    //…
      ReadContextId(message);
      return message;
}

Ezen kívül ezek a csatorna-implementációk delegálják a metódushívásokat az alattuk lévő csatornára a csatorna veremében. A munkamenet-alapú változatok azonban egy alapszintű logikával rendelkeznek, amely biztosítja, hogy a környezetazonosító elküldve legyen, és csak az első üzenethez legyen beolvasva, amely a munkamenet létrehozását okozza.

if (isFirstMessage)
{
//…
    this.ApplyContext(message);
    isFirstMessage = false;
}

Ezeket a csatorna-implementációkat az osztály és DurableInstanceContextBindingElement az osztály megfelelő módon adja hozzá a DurableInstanceContextBindingElementSection WCF-csatorna futtatókörnyezetéhez. A kötési elemekről és a kötéselemek szakaszairól a HttpCookieSession-csatorna mintadokumentációjában olvashat bővebben.

Szolgáltatásmodell-rétegbővítmények

Most, hogy a környezetazonosító áthaladt a csatornarétegen, a szolgáltatás viselkedése implementálható a példányosítás testreszabásához. Ebben a példában egy tárolókezelővel tölthetők be és menthetők az állapotok az állandó tárolóból vagy az állandó tárolóba. A korábban ismertetett módon ez a minta egy olyan tárolókezelőt biztosít, amely az SQL Server 2005-öt használja háttértárként. Azonban egyéni tárolási mechanizmusokat is hozzáadhat ehhez a bővítményhez. Ehhez nyilvános felületet deklarálnak, amelyet minden tárolókezelőnek végre kell hajtania.

public interface IStorageManager
{
    object GetInstance(string contextId, Type type);
    void SaveInstance(string contextId, object state);
}

Az SqlServerStorageManager osztály tartalmazza az alapértelmezett IStorageManager implementációt. SaveInstance A metódusban az adott objektum szerializálva van az XmlSerializer használatával, és az SQL Server-adatbázisba lesz mentve.

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

A metódusban a GetInstance szerializált adatok beolvasva lesznek egy adott környezeti azonosítóhoz, és az abból létrehozott objektum vissza lesz adva a hívónak.

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

A tárkezelők felhasználóinak nem szabad közvetlenül példányosítaniuk őket. Az osztályt StorageManagerFactory használják, amely a Storage Manager létrehozási részleteiből absztrakciót tartalmaz. Ennek az osztálynak egy statikus tagja van, GetStorageManageramely egy adott tárkezelő típusú példányt hoz létre. Ha a típusparaméter az null, ez a metódus létrehozza az alapértelmezett SqlServerStorageManager osztály egy példányát, és visszaadja. Emellett ellenőrzi az adott típust, hogy biztosan megvalósítsa az interfészt 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;
}
}

A példányok állandó tárolóból való olvasásához és írásához szükséges infrastruktúra implementálva van. Most meg kell tenni a szolgáltatás viselkedésének módosításához szükséges lépéseket.

Ennek a folyamatnak az első lépéseként menteni kell a környezetazonosítót, amely a csatornarétegen keresztül az aktuális InstanceContextre került. Az InstanceContext egy futtatókörnyezeti összetevő, amely a WCF-diszpécser és a szolgáltatáspéldány közötti kapcsolatként működik. A szolgáltatáspéldány további állapotának és viselkedésének biztosítására használható. Ez azért lényeges, mert a munkamenet-alapú kommunikáció során a környezetazonosító csak az első üzenettel lesz elküldve.

A WCF lehetővé teszi az InstanceContext futtatókörnyezet-összetevő kiterjesztését egy új állapot és viselkedés hozzáadásával a bővíthető objektummintával. Az bővíthető objektumminta a WCF-ben a meglévő futtatókörnyezeti osztályok új funkciókkal való kiterjesztésére vagy új állapotfunkciók objektumhoz való hozzáadására szolgál. A bővíthető objektummintában három interfész található : IExtensibleObject<T>, IExtension<T> és IExtensionCollection<T>:

  • Az IExtensibleObject<T> felületet olyan objektumok implementálják, amelyek lehetővé teszik a funkciók testreszabását lehetővé tevő bővítményeket.

  • Az IExtension<T> interfészt olyan objektumok implementálják, amelyek A típusú osztályok kiterjesztései.

  • Az IExtensionCollection<T> felület olyan IExtensions-gyűjtemény, amely lehetővé teszi az IExtensions típus szerinti lekérését.

Ezért létre kell hozni egy InstanceContextExtension osztályt, amely implementálja az IExtension felületet, és meghatározza a környezetazonosító mentéséhez szükséges állapotot. Ez az osztály a használt tárolókezelő tárolásának állapotát is biztosítja. Az új állapot mentése után nem lehet módosítani. Ezért az állapotot a rendszer a létrehozásakor adja meg és menti a példányhoz, majd csak írásvédett tulajdonságok használatával érhető el.

// 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; }
}

Az InstanceContextInitializer osztály implementálja az IInstanceContextInitializer felületet, és hozzáadja a példánykörnyezet bővítményét a létrehozandó InstanceContext Bővítmények gyűjteményéhez.

public void Initialize(InstanceContext instanceContext, Message message)
{
    string contextId =
  (string)message.Properties[DurableInstanceContextUtility.ContextIdProperty];

    DurableInstanceContextExtension extension =
                new DurableInstanceContextExtension(contextId,
                     storageManager);
    instanceContext.Extensions.Add(extension);
}

A korábban ismertetett módon a környezetazonosító az osztály gyűjteményéből PropertiesMessage lett beolvasva, és átadva a bővítményosztály konstruktorának. Ez bemutatja, hogyan lehet egységesen kicserélni az információkat a rétegek között.

A következő fontos lépés a szolgáltatáspéldány-létrehozási folyamat felülírása. A WCF lehetővé teszi az egyéni példányosítási viselkedések implementálását és a futtatókörnyezethez való csatlakoztatását az IInstanceProvider felületen. Az új InstanceProvider osztály implementálva van a feladat végrehajtásához. A konstruktor elfogadja a példányszolgáltatótól várt szolgáltatástípust. Később ez új példányok létrehozására szolgál. A megvalósítás során GetInstance létrejön egy tárkezelő egy példánya, amely egy tartós példányt keres. Ha visszaadja null, a rendszer a szolgáltatástípus egy új példányát példányosít, és visszaadja a hívónak.

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

A következő fontos lépés az , InstanceContextExtensionés InstanceContextInitializer az InstanceProviderosztályok telepítése a szolgáltatásmodell futtatókörnyezetébe. Egy egyéni attribútummal megjelölheti a szolgáltatás-implementációs osztályokat a viselkedés telepítéséhez. Ez DurableInstanceContextAttribute tartalmazza az attribútum implementálását, és implementálja a felületet a IServiceBehavior teljes szolgáltatás-futtatókörnyezet kibővítéséhez.

Ennek az osztálynak van egy tulajdonsága, amely elfogadja a használni kívánt tárolókezelő típusát. Ily módon a megvalósítás lehetővé teszi a felhasználók számára, hogy saját implementációt IStorageManager adjanak meg ennek az attribútumnak a paramétereként.

A megvalósítás során ApplyDispatchBehavior a rendszer ellenőrzi az InstanceContextMode aktuális ServiceBehavior attribútumot. Ha ez a tulajdonság Singleton értékre van állítva, a tartós instancing engedélyezése nem lehetséges, és InvalidOperationException a rendszer értesítést küld a gazdagépnek.

ServiceBehaviorAttribute serviceBehavior =
    serviceDescription.Behaviors.Find<ServiceBehaviorAttribute>();

if (serviceBehavior != null &&
     serviceBehavior.InstanceContextMode == InstanceContextMode.Single)
{
    throw new InvalidOperationException(
       ResourceHelper.GetString("ExSingletonInstancingNotSupported"));
}

Ezt követően a rendszer létrehozza és telepíti a tárkezelő példányait, a példánykörnyezet-inicializálót és a példányszolgáltatót minden DispatchRuntime végponthoz.

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

Összefoglalva, ez a minta egy olyan csatornát hozott létre, amely lehetővé tette az egyéni környezetazonosító-csere egyéni vezetékes protokollját, és felülírja az alapértelmezett instancing viselkedést is, hogy betöltse a példányokat az állandó tárolóból.

A szolgáltatáspéldányt az állandó tárolóba mentheti. Ahogy korábban említettük, már létezik a szükséges funkciók az állapot implementációban IStorageManager való mentéséhez. Ezt most integrálni kell a WCF-futtatókörnyezettel. Egy másik attribútumra van szükség, amely a szolgáltatás-implementációs osztály metódusaira alkalmazható. Ezt az attribútumot a szolgáltatáspéldány állapotát módosító metódusokra kell alkalmazni.

Az SaveStateAttribute osztály implementálja ezt a funkciót. Emellett osztályt IOperationBehavior is implementál az egyes műveletek WCF-futtatókörnyezetének módosításához. Ha egy metódus ezzel az attribútummal van megjelölve, a WCF-futtatókörnyezet meghívja a ApplyBehavior metódust a megfelelő DispatchOperation létrehozása közben. A metódus implementálásában egyetlen kódsor található:

dispatch.Invoker = new OperationInvoker(dispatch.Invoker);

Ez az utasítás létrehoz egy típuspéldányt OperationInvoker , és hozzárendeli a InvokerDispatchOperation létrehozandó tulajdonsághoz. Az OperationInvoker osztály a számára létrehozott alapértelmezett művelethívó burkolója DispatchOperation. Ez az osztály implementálja az interfészt IOperationInvoker . A metódus implementálásában a Invoke rendszer delegálja a tényleges metódushívást a belső műveletmeghívóhoz. Az eredmények visszaadása előtt azonban a tárkezelő InstanceContext a szolgáltatáspéldány mentésére szolgál.

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;

A bővítmény használata

A csatornaréteg és a szolgáltatásmodell rétegbővítményei is elkészültek, és most már használhatók WCF-alkalmazásokban is. A szolgáltatásoknak egyéni kötéssel kell hozzáadniuk a csatornát a csatornaveremhez, majd meg kell jelölniük a szolgáltatás-implementációs osztályokat a megfelelő attribútumokkal.

[DurableInstanceContext]
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
public class ShoppingCart : IShoppingCart
{
//…
     [SaveState]
     public int AddItem(string item)
     {
         //…
     }
//…
 }

Az ügyfélalkalmazások egyéni kötéssel kell hozzáadniuk a DurableInstanceContextChannelt a csatornaveremhez. Ha a csatornát deklaratív módon szeretné konfigurálni a konfigurációs fájlban, a kötéselem-szakaszt hozzá kell adni a kötéselem-bővítmények gyűjteményéhez.

<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>

A kötési elem mostantól ugyanúgy használható egyéni kötéssel, mint a többi standard kötési elem:

<bindings>
 <customBinding>
   <binding name="TextOverHttp">
     <durableInstanceContext contextType="HttpCookie"/>
     <reliableSession />
     <textMessageEncoding />
     <httpTransport />
   </binding>
 </customBinding>
</bindings>

Összegzés

Ez a minta bemutatta, hogyan hozhat létre egyéni protokollcsatornát, és hogyan szabhatja testre a szolgáltatás viselkedését annak engedélyezéséhez.

A bővítmény tovább fejleszthető, ha lehetővé teszi a felhasználók számára, hogy egy konfigurációs szakasz használatával határozzák meg a IStorageManager megvalósítást. Ez lehetővé teszi a háttértár módosítását a szolgáltatáskód újrafordítása nélkül.

Emellett megpróbálhat implementálni egy osztályt (például StateBag), amely magában foglalja a példány állapotát. Ez az osztály felelős az állapot megőrzéséért, amikor változik. Így elkerülheti az SaveState attribútum használatát, és pontosabban hajthatja végre a megőrzési munkát (például megőrizheti az állapotot az állapot tényleges módosításakor, ahelyett, hogy minden alkalommal mentenél, amikor egy metódust meghívnak az SaveState attribútummal).

A minta futtatásakor a következő kimenet jelenik meg. Az ügyfél két elemet ad hozzá a bevásárlókocsihoz, majd lekéri a kosárban lévő elemek listáját a szolgáltatásból. A szolgáltatás és az ügyfél leállításához nyomja le az ENTER billentyűt az egyes konzolablakokban.

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

Feljegyzés

A szolgáltatás újraépítése felülírja az adatbázisfájlt. A minta több futtatása során megőrzött állapot megfigyeléséhez ügyeljen arra, hogy ne építse újra a mintát a futtatások között.

A minta beállítása, összeállítása és futtatása

  1. Győződjön meg arról, hogy elvégezte a Windows Communication Foundation-minták egyszeri beállítási eljárását.

  2. A megoldás létrehozásához kövesse a Windows Communication Foundation-minták készítésére vonatkozó utasításokat.

  3. Ha a mintát egy vagy több gép közötti konfigurációban szeretné futtatni, kövesse a Windows Communication Foundation-minták futtatásával kapcsolatos utasításokat.

Feljegyzés

A minta futtatásához SQL Server 2005-öt vagy SQL Express 2005-öt kell futtatnia. Ha SQL Server 2005-öt futtat, módosítania kell a szolgáltatás kapcsolati sztring konfigurációját. Gépközi futtatás esetén az SQL Server csak a kiszolgálógépen szükséges.