So wird es gemacht: Entwickeln eines Instanzsteuerungsanbieters

Das folgende Verfahren beschreibt die Schritte zum Erstellen eines benutzerdefinierten Instanzsteuerungsanbieters.

  1. Erstellen Sie ein Klassenbibliotheksprojekt.

  2. Fügen Sie Microsoft.ApplicationServer.StoreManagement einen Verweis hinzu. Fügen Sie darüber hinaus der Assembly System.Configuration einen Verweis hinzu, um den Beispielcode in diesem Thema zu kompilieren.

  3. Fügen Sie die folgende Anweisung am Anfang der Quelldatei hinzu.

    using Microsoft.ApplicationServer.StoreManagement.Control;
    using Microsoft.ApplicationServer.StoreManagement.Control;
    using System.Data.SqlClient;
    using System.Collections.Specialized;
    using System.Threading;
    using System.Data;
    
  4. Erstellen Sie eine Klasse für den Instanzsteuerungsanbieter, die aus der Klasse InstanceControlProvider abgeleitet ist.

        public class MySqlInstanceControlProvider : InstanceControlProvider
        {
        }
    
  5. Implementieren Sie die Initialize-Methode. Diese Methode akzeptiert einen Eigenschaftenbehälter, der den in der Konfigurationsdatei angegebenen Konfigurationsinformationen entspricht. Die in diesem Eigenschaftenbehälter vorhandenen Daten werden zur Konstruktion des Anbieters verwendet. Die Methode Initialize wird vor den Methoden CreateInstanceControl oder UniqueProviderIdentifier aufgerufen.

    Hinweis

    In Remoteszenarien würde die Name/Wert-Auflistung ein Element mit Namen EnableServiceModelMetadata enthalten. Der Anbieter kann diesen Parameter ignorieren und vor dem Aufruf der baß.Initialize-Methode entfernen. Diese Eigenschaft wird normalerweise verwendet, um festzustellen, ob für das Microsoft.Web.Administration.ServerManager-Objekt SetMetadata(„ServiceModel“, true) aufgerufen werden soll.

    
            string ConnectionString { get; set; }
    
            public override void Initialize(string name, NameValueCollection config)
            {
    
                this.ConnectionString = config["connectionString"];
    
                // Initialize the base class
                base.Initialize(name, config);
            }
    
  6. Implementieren Sie die CreateInstanceControl-Methode der InstanceControlProvider-Klasse, um ein benutzerdefiniertes InstanceControl-Objekt zurückzugeben, das der Client für den Zugriff auf ein CommandSend- oder ein CommandReceive-Objekt verwendet.

            public override InstanceControl CreateInstanceControl()
            {
                SqlConnectionStringBuilder connectionStringBuilder = new SqlConnectionStringBuilder(this.ConnectionString);
                connectionStringBuilder.AsynchronousProcessing = true;
                return new MySqlInstanceControl(connectionStringBuilder.ConnectionString);
            }
    

    Hinweis

    Informationen zur Implementierung des MySqlInstanceControl-Typs finden Sie im folgenden Abschnitt.

  7. Implementieren Sie die UniqueProviderIdentifier-Methode. Die eindeutige Anbieter-ID, die von dieser Methode zurückgegeben wird, wird zur Bestimmung verwendet, ob verschiedene Anbieterobjekte zum gleichen zugrunde liegenden Informationsspeicher aufgelöst werden.

            string UniqueStoreIdentifier { get; set; }
    
            public override string UniqueProviderIdentifier()
            {   
                this.UniqueStoreIdentifier = GetUniqueStoreIdentifier(this.ConnectionString); 
                return this.UniqueStoreIdentifier;
            }
    
            private string GetUniqueStoreIdentifier(string connectionString)
            {
                using (SqlConnection connection = new SqlConnection(connectionString))
                {
                    using (SqlCommand command = new SqlCommand())
                    {
                        command.CommandType = System.Data.CommandType.Text;
                        command.CommandText = "SELECT TOP (1) [StoreIdentifier] FROM [Microsoft.ApplicationServer.DurableInstancing].[StoreVersion]";
                        command.Connection = connection;
    
                        command.Connection.Open();
    
                        Guid identifier = (Guid)command.ExecuteScalar();
                        return identifier.ToString();
                    }
                }
            }
    

Implementieren von „InstanceControl“

Das folgende Verfahren beschreibt die Schritte zum Erstellen eines benutzerdefinierten InstanceControl-Typs.

  1. Erstellen Sie eine Klasse, die von der InstanceControl-Klasse abgeleitet wird.

        public class MySqlInstanceControl : InstanceControl
        {
            readonly string connectionString;
             public MySqlInstanceControl(string connectionString)
             {
                 this.connectionString = connectionString;
             }
        }
    
  2. Implementieren Sie die CommandReceive-Eigenschaft. Die Accessormethode Get der CommandReceive-Eigenschaft sollte ein CommandReceive-Objekt zurückgeben. Ein Client ruft Methoden für dieses Objekt auf, um Befehle aus der Befehlswarteschlange asynchron zu empfangen.

            MySqlCommandReceive commandReceive;
            public override CommandReceive CommandReceive
            {
                get 
                {
                    if (this.commandReceive == null)
                    {
                        MySqlCommandReceive tmp = new MySqlCommandReceive(this.connectionString);
                        Interlocked.CompareExchange(ref this.commandReceive, tmp, null);
                    }
                    return this.commandReceive;
                }
            }
    
  3. Implementieren Sie die CommandSend-Eigenschaft, und Sie geben mit der Accessormethode Get ein benutzerdefiniertes CommandSend-Objekt zurück. Die Methode Get der CommandSend-Eigenschaft sollte ein CommandSend-Objekt zurückgeben. Ein Client ruft Methoden dieses Objekts auf, um Befehle asynchron an die Befehlswarteschlange zu senden.

            MySqlCommandSend commandSend;
            public override CommandSend CommandSend
            {
                get
                {
                    if (this.commandSend == null)
                    {
                        MySqlCommandSend tmp = new MySqlCommandSend(this.connectionString);
                        Interlocked.CompareExchange(ref this.commandSend, tmp, null);
                        return this.commandSend;
                    }
                    return this.CommandSend;
                }
            }
    

    Der Client verwendet diese beiden Objekte zum Senden von Befehlen an die Befehlswarteschlange (in die Warteschlange stellen) und zum Empfangen von Befehlen aus der Befehlswarteschlange (aus der Warteschlange abrufen). Beispielsweise stellt ein Instanzsteuerungs-Cmdlet einen Befehl mithilfe des CommandSend-Objekts in die Befehlswarteschlange ein, und der Workflowverwaltungsdienst (WMS, Workflow Management Service) liest den Befehl mithilfe des CommandReceive-Objekts aus der Befehlswarteschlange aus. Unter bestimmten Umständen, etwa wenn das Remove-ASAppServiceInstance-Cmdlet ausgeführt wird, verarbeitet der Speicher den Befehl selbst, um die Instanz aus dem Instanzspeicher zu entfernen.

    Hinweis

    Informationen zu Implementierungen der Typen MySqlCommandSend und MySqlCommandReceive finden Sie in den folgenden Abschnitten.

Implementieren von „CommandSend“

So erstellen Sie einen benutzerdefinierten CommandSend-Typ:

  • Erstellen Sie eine Klasse, die von der CommandSend-Klasse abgeleitet wird, und implementieren Sie die Methoden BeginTrySend und EndTrySend.

        public class MySqlCommandSend : CommandSend
        {
            readonly string connectionString;
    
            public MySqlCommandSend(string connectionString)
            {
                this.connectionString = connectionString;
            }
    
            public override IAsyncResult BeginSend(InstanceCommand command, TimeSpan timeout, AsyncCallback callback, object state)
            {
                throw new NotImplementedException();
            }
    
            public override void EndSend(IAsyncResult result)
            {
                throw new NotImplementedException();
            }
        }
    

Implementieren von „CommandReceive“

So erstellen Sie einen benutzerdefinierten CommandReceive-Typ:

  • Erstellen Sie eine Klasse, die von der CommandReceive-Klasse abgeleitet wird, und implementieren Sie die Methoden BeginTryReceive und EndTryReceive.

        public class MySqlCommandReceive : CommandReceive
        {
            readonly string connectionString;
    
            Queue<MySqlReceivedInstanceCommand> receivedInstanceCommands;
    
            public MySqlCommandReceive(string connectionString)
            {
                this.connectionString = connectionString;
                this.receivedInstanceCommands = new Queue<MySqlReceivedInstanceCommand>();          
            }
    
            public override IAsyncResult BeginTryReceive(TimeSpan timeout, AsyncCallback callback, object state)
            {
                throw new NotImplementedException();
            }
    
            public override bool EndTryReceive(IAsyncResult result, out ReceivedInstanceCommand command)
            {
                throw new NotImplementedException();
            }
        }
    

    Hinweis

    Im folgenden Abschnitt finden Sie Informationen zur Implementierung der MySqlReceivedInstanceCommand-Klasse.

Implementieren von „ReceivedInstanceCommand“

So erstellen Sie einen benutzerdefinierten ReceivedInstanceCommand-Typ:

  • Erstellen Sie eine Klasse, die von der ReceivedInstanceCommand-Klasse abgeleitet wird, und implementieren Sie die InstanceCommandContext-Eigenschaft.

        class MySqlReceivedInstanceCommand : ReceivedInstanceCommand
        {
            long commandId;
            MySqlCommandReceive receiver;
            MySqlInstanceCommandContext context;
    
            internal MySqlReceivedInstanceCommand(long commandId,
                 Guid instanceId, Microsoft.ApplicationServer.StoreManagement.Control.CommandType commandType, IDictionary<string, string> serviceIdentifier, TimeSpan timeout,
                MySqlCommandReceive receiver) : base()
            {
                this.commandId = commandId;
                base.CommandType = commandType;
                base.InstanceId = instanceId;
                base.ServiceIdentifier = serviceIdentifier;
                //this.CommandTimeout = new TimeoutHelper(timeout, true);
                this.receiver = receiver;
                this.context = new MySqlInstanceCommandContext(this);
            }
            public override InstanceCommandContext InstanceCommandContext
            {
                get
                {
                    return this.context;
                }
            }
        }
    

    Hinweis

    Im folgenden Abschnitt finden Sie Informationen zur Implementierung des MySqlInstanceCommandContext-Typs.

Implementieren von „InstanceCommandContext“

So erstellen Sie einen benutzerdefinierten InstanceCommandContext-Typ:

  • Erstellen Sie eine Klasse, die von der InstanceCommandContext-Klasse abgeleitet wird, und implementieren Sie die Methoden BeginComplete, EndComplete, BeginAbandon und EndAbandon.

    Ein Client ruft die BeginComplete-Methode für das InstanceCommandContext-Objekt auf, um eine Benachrichtigung auszugeben, dass der Befehl erfolgreich ausgeführt wurde. Anschließend sollte der Steuerungsanbieter den Befehl aus der Befehlswarteschlange entfernen. WMS ruft diese Methode auf, wenn der Befehl erfolgreich ausgeführt wurde.

    Ein Client ruft die BeginAbandon-Methode für das InstanceCommandContext-Objekt auf, um eine Benachrichtigung auszugeben, dass die Befehlsausführung fehlgeschlagen ist. Die Entscheidung, wie mit dem Befehl verfahren werden soll, liegt beim Instanzsteuerungsanbieter. Beispielsweise kann ein Steuerungsanbieter die Befehlsausführung für eine festgelegte Anzahl von Versuchen wiederholen, bevor er den Befehl aus der Befehlswarteschlange entfernt. WMS ruft diese Methode auf, wenn die Befehlsausführung fehlschlägt.

        class MySqlInstanceCommandContext : InstanceCommandContext
        {
            MySqlReceivedInstanceCommand command;
    
            internal MySqlInstanceCommandContext(MySqlReceivedInstanceCommand command)
            {
                this.command = command;
            }
    
            public override IAsyncResult BeginAbandon(Exception exception, TimeSpan timeout, AsyncCallback callback, object state)
            {
                throw new NotImplementedException();
            }
    
            public override IAsyncResult BeginComplete(TimeSpan timeout, AsyncCallback callback, object state)
            {
                throw new NotImplementedException();
            }
    
            public override void EndAbandon(IAsyncResult result)
            {
                throw new NotImplementedException();
            }
    
            public override void EndComplete(IAsyncResult result)
            {
                throw new NotImplementedException();
            }
        }
    

Siehe auch

Konzepte

So wird es gemacht: Entwickeln eines Instanzspeicheranbieters
So wird es gemacht: Entwickeln eines Instanzabfrageanbieters
So wird es gemacht: Konfigurieren von Instanzspeicher-, Instanzabfrage- und Instanzsteuerungsanbieter
Instanzspeicher-, Instanzabfrage- und Instanzsteuerungsanbieter

  2011-12-05