Beispiel für Datei-Persistenz-Provider

Dieses Beispiel veranschaulicht, wie ein Persistenz-Provider erstellt wird, der mit permanenten Diensten arbeitet. Der Zustand der Dienstinstanz wird in Dateien auf dem Computer gespeichert.

Das Beispiel enthält auch eine Rechnerdienstimplementierung, die mit dem Permanente Dienste identisch ist. Der Unterschied ist, dass dieser Dienst den im Beispiel erstellten Datei-Persistenz-Provider verwendet und nicht den standardmäßigen Locking SQL-Persistenz-Provider.

Tipp

Zum Erstellen und Ausführen dieses Beispiels muss .NET Framework, Version 3.5 installiert sein. Zum Öffnen des Projekts und der Projektmappendateien ist Visual Studio 2008 erforderlich.

Das Beispiel für Rechnerclient muss mit diesem Dienst ausgeführt werden (Weitere Informationen finden Sie unter zu den Verfahren zum Einrichten finden Sie am Ende dieses Themas).

Datei-Persistenz-Provider

Der Datei-Persistenz-Provider in diesem Beispiel wird in der Datei "FilePersistenceProviderFactory.cs" definiert. Beachten Sie, dass sich die tatsächliche FilePersistenceProvider-Klasse in einer eingebetteten Klasse befindet. Zur Erstellung des Datei-Persistenz-Providers wird ein Factorymuster verwendet, in der die Factory die tatsächliche Persistenz-Provider-Klasse bei Bedarf an die Dienstlaufzeit übergibt. Dies ist die Standardmöglichkeit, Anbieter in WCF zu erstellen.

Die Datei-Persistenz-Provider-Factoryklasse erbt von der abstrakten PersistenceProviderFactory-Klasse. Die abstrakte PersistenceProviderFactory-Klasse wird im folgenden Code definiert.

namespace System.ServiceModel.Persistence
{
    public abstract class PersistenceProviderFactory : CommunicationObject
    {
        protected PersistenceProviderFactory();

        public abstract PersistenceProvider CreateProvider(Guid id);
    }
}

Beachten Sie, dass PersistenceProviderFactory von der abstrakten CommunicationObject-Klasse erbt. CommunicationObject stellt die Methoden bereit, die erforderlich sind, um die Lebensdauer des Objekts während seiner Verwendung in der Dienstlaufzeit zu verwalten.

Das Factorymuster für den Provider stellt sicher, dass die Factory alle Ressourcen verwaltet, die in allen Instanzen des Providers gleich sind. Im Fall des Datei-Persistenz-Providers kann die Factory beispielsweise festlegen, wo die Persistenz-Dateien gespeichert und anschließend für alle Instanzen des tatsächlichen Datei-Persistenz-Providers freigegeben werden.

Als Ergebnis ist eine Instanz des Providers für jede Instanz des Diensts vorhanden. Es ist auch eine Instanz der Factory für jeden Host vorhanden.

Der Datei-Persistenz-Provider selbst erbt von der abstrakten PersistenceProvider-Klasse. Diese Klasse wird im folgenden Code definiert.

namespace System.ServiceModel.Persistence
{
    public abstract class PersistenceProvider : CommunicationObject
    {
        protected PersistenceProvider(Guid id);

        public Guid Id { get; }

        public abstract IAsyncResult BeginCreate(object instance, TimeSpan timeout, AsyncCallback callback, object state);
        public abstract IAsyncResult BeginDelete(object instance, TimeSpan timeout, AsyncCallback callback, object state);
        public abstract IAsyncResult BeginLoad(TimeSpan timeout, AsyncCallback callback, object state);
        public virtual IAsyncResult BeginLoadIfChanged(TimeSpan timeout, object instanceToken, AsyncCallback callback, object state);
        public abstract IAsyncResult BeginUpdate(object instance, TimeSpan timeout, AsyncCallback callback, object state);
        public abstract object Create(object instance, TimeSpan timeout);
        public abstract void Delete(object instance, TimeSpan timeout);
        public abstract object EndCreate(IAsyncResult result);
        public abstract void EndDelete(IAsyncResult result);
        public abstract object EndLoad(IAsyncResult result);
        public virtual bool EndLoadIfChanged(IAsyncResult result, out object instance);
        public abstract object EndUpdate(IAsyncResult result);
        public abstract object Load(TimeSpan timeout);
        public virtual bool LoadIfChanged(TimeSpan timeout, object instanceToken, out object instance);
        public abstract object Update(object instance, TimeSpan timeout);    
    }
}

Die Persistenz-Provider-Klasse ist auch ein Kommunikationsobjekt. Der Persistenz-Provider enthält vier Methoden: Create(), Update(), Load() und Delete(). Es werden sowohl asynchrone Varianten dieser Methoden definiert als auch Überlastungen der asynchronen Varianten. Die folgenden Regeln gelten, um den Zustand der Instanz in den Dateien zu speichern:

  • Die tatsächlichen Dateien werden auf dem Computer, auf dem die Dateien gehostet werden, in einem Unterverzeichnis namens FilePersistenceProvider im Verzeichnis Temp gespeichert.
  • Der Zustand einer Instanz wird in einer Datei gespeichert, deren Name der eindeutige Bezeichner der Instanz ist. Diese Datei wird mit der Erweiterung ".bin" gespeichert.
  • Wenn eine Datei gelöscht werden muss, wird sie nicht tatsächlich gelöscht, sondern zu "gelöscht" umbenannt.

Konfiguration des Persistenz-Providers

Bevor der Datei-Persistenz-Provider verwendet werden kann, muss er in der Konfigurationsdatei für den Dienst angegeben werden. Die Konfiguration des Persistenz-Providers wird im Abschnitt servicebBehaviors der Konfigurationsdatei festgelegt. Dieses Beispiel zeigt den Eintrag in der Datei "Web.config":

<behaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehavior"  >
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
          <serviceCredentials>
            <windowsAuthentication allowAnonymousLogons="false" includeWindowsGroups="true" />
          </serviceCredentials>
          <persistenceProvider type="Microsoft.WorkflowServices.Samples.FilePersistenceProviderFactory, DurableServiceFactory, Version=1.0.0.0"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>  

Code für permanente Dienste – Dienstvertrag

Im folgenden Codebeispiel wird der Dienstvertrag für den Rechnerdienst veranschaulicht.

[ServiceContract(Namespace = "http://Microsoft.WorkflowServices.Samples")]
    public interface ICalculator
    {
        [OperationContract()]
        int PowerOn();
        [OperationContract()]
        int Add(int value);
        [OperationContract()]
        int Subtract(int value);
        [OperationContract()]
        int Multiply(int value);
        [OperationContract()]
        int Divide(int value);
        [OperationContract()]
        void PowerOff();
    }  

Dienstimplementierung

Im folgenden Code wird mit dem DurableServiceAttribute-Attribut in der Dienstimplementierung angegeben, dass es sich um einen permanenten Dienst handelt.

[Serializable]
[DurableService]
public class DurableCalculator : ICalculator
{
    int currentValue = default(int);

    [DurableOperation(CanCreateInstance=true)]
    public int PowerOn()
    {
        return currentValue;
    }

    [DurableOperation()]
    public int Add(int value)
    {
        return (currentValue += value);
    }

    [DurableOperation()]
    public int Subtract(int value)
    {
        return (currentValue -= value);
    }

    [DurableOperation()]
    public int Multiply(int value)
    {
        return (currentValue *= value);
    }

    [DurableOperation()]
    public int Divide(int value)
    {
        return (currentValue /= value);
    }

    [DurableOperation(CompletesInstance=true)]
    public void PowerOff()
    {
    }

}

Das DurableOperationAttribute-Attribut gibt an, dass der Dienstinstanzzustand gespeichert wird, nachdem der Vorgang abgeschlossen wurde.

Es gibt zwei Parameter, die im DurableOperationAttribute-Attribut verwendet werden können. Die CanCreateInstance-Eigenschaft gibt an, dass die Instanz beim Aufrufen des Vorgangs erstellt wird. Die CompletesInstance-Eigenschaft legt fest, dass die Dienstinstanz beendet wird, nachdem der Vorgang, für den dieses Attribut festgelegt wurde, nicht mehr ausgeführt wird. Der Zustand wird ebenfalls aus der Datenbank gelöscht, nachdem der Vorgang abgeschlossen wurde.

Im folgenden Code wird die SVC-Datei zum Hosten dieses Beispiels in Internetinformationsdienste (IIS) veranschaulicht.

<%@ServiceHost language=c# Debug="true" Service="Microsoft.WorkflowServices.Samples.DurableCalculator" Factory="System.ServiceModel.Activation.ServiceHostFactory" %>

Die Bindung für den Dienst wird in der Datei "Web.config" konfiguriert. Mithilfe der WSHttpContextBinding-Bindung kann der Kontext zum Weiterleiten von Anforderungen an eine bestimmte Anwendungsinstanz beibehalten werden. Der Persistenz-Provider-Eintrag, der den Persistenz-Provider angibt, befindet sich im Abschnitt ServiceBehaviors.

So richten Sie das Beispiel ein, erstellen es und führen es aus

  1. Führen Sie in jedem Fall die Setupanweisungen in Beispiele zum einmaligen Setupverfahren für Windows Communication Foundation aus.

  2. Aktivieren Sie in IIS im virtuellen Verzeichnis "ServiceModelSamples" die Windows-Authentifizierung.

    So aktivieren Sie die Windows-Authentifizierung in IIS 5.1 oder 6.0

    1. Öffnen Sie ein Eingabeaufforderungsfenster, und geben Sie start inetmgr ein, um MMC-Snap-In Internetinformationsdienste (IIS) zu öffnen.
    2. Klicken Sie mit der rechten Maustaste auf das virtuelle Stammverzeichnis ServiceModelSamples in Standardwebsite, klicken Sie auf Eigenschaften, und klicken Sie dann auf die Registerkarte Verzeichnissicherheit.
    3. Klicken Sie unter Authentifizierung und Zugriffssteuerung auf Bearbeiten.
    4. Wählen Sie im Dialogfeld Authentifizierungsmethoden die Option Integrierte Windows-Authentifizierung aus.

    So aktivieren Sie die Windows-Authentifizierung in IIS 7.0

    1. Öffnen Sie ein Eingabeaufforderungsfenster, und geben Sie start inetmgr ein, um das MMC-Snap-In Internetinformationsdienste (IIS) zu öffnen.
    2. Wählen Sie das virtuelle Stammverzeichnis ServiceModelSamples unter Standardwebsite aus.
    3. Doppelklicken Sie im Startbereich ServiceModelSamples in der Gruppe IIS auf Authentifizierung.
    4. Wählen Sie Windows-Authentifizierung aus, und wählen Sie die Aktion Aktivieren aus.
  3. Erstellen Sie das Projekt. Das Projekt erstellt und aktualisiert ServiceModelSamples.

  4. Um sicherzustellen, dass der Dienst richtig installiert ist, zeigen Sie auf die Adresse https://localhost/servicemodelsamples/service.svc. Es sollte die Hilfeseite für den Dienst angezeigt werden. Geben Sie zum Anzeigen der Web Services Descriptor Language (WSDL) https://localhost/servicemodelsamples/service.svc?wsdl ein.

  5. Zum Ausführen dieses Beispiels müssen Sie Beispiel für Rechnerclient verwenden. Dies ist eine mit Windows Presentation Foundation (WPF) erstellte Rechnerbenutzerschnittstelle, die als Client für den Dienst fungiert. Damit Sie testen können, ob der Dienst permanent ist, schließen Sie den Client, und öffnen Sie ihn erneut, während der Rechnerdienst ausgeführt wird. Der Rechnerclient kommuniziert mit der gleichen Dienstinstanz. Die Instanz-ID wird unten angezeigt. Der Rechnerclient verwendet die Textdatei "Client.ctx" zum Speichern des Kontexts an einem permanenten Speicherort, wenn der erste Aufruf ausgeführt wird (in diesem Beispiel im Verzeichnis "\bin" des Beispiels). Wenn Sie den Client erneut öffnen, überprüft er, ob die Datei vorhanden ist. Wenn die Datei vorhanden ist, wird der gespeicherte Kontext auf den erstellten Kanal angewendet. Wenn der Dienst abgeschlossen wurde und Sie den Client öffnen, während sich die Datei "Client.ctx" noch im Verzeichnis "\bin" befindet, wird versucht, den Kontext auf den Kanal anzuwenden. Es wird ein Fehler angezeigt, da der Dienst, mit dem kommuniziert werden soll, nicht vorhanden ist. Löschen Sie die Datei, und versuchen Sie es erneut.

  6. Sie können den Dienst auch wiederverwenden, indem Sie IIS neu starten. Da Sie nach jedem Vorgang einen Persistenzspeicher verwenden, wird der Zustand des Diensts gespeichert. Wenn Sie daher nach dem Neustart von IIS auf dem Client versuchen, mit dem Dienst zu kommunizieren, empfängt die Dienstinfrastruktur die Instanz vom Persistenzspeicher, und Sie können mit der gleichen Instanz kommunizieren.

    Tipp

    Wenn Sie einen Vorgang zum ersten Mal nach dem Neustart von IIS aufrufen, wird eine MessageSecurityException-Ausnahme ausgelöst. Dies wird durch ein abgelaufenes Sicherheitstoken im Kanal verursacht. Wenn Sie einen anderen Vorgang aufrufen, ist der Aufruf erfolgreich.

Send comments about this topic to Microsoft.
© 2007 Microsoft Corporation. All rights reserved.