Procedura: sviluppare un provider di controllo di istanza

Nella procedura seguente viene descritto come creare un provider di controllo di istanza personalizzato.

  1. Creare un progetto Libreria di classi.

  2. Aggiungere un riferimento all'elemento Microsoft.ApplicationServer.StoreManagement. Aggiungere, inoltre, un riferimento all'assembly System.Configuration per la compilazione del codice di esempio illustrato in questo argomento.

  3. Aggiungere l'istruzione seguente all'inizio del file di origine.

    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. Creare una classe per il provider di controllo di istanza personalizzato derivata dalla classe InstanceControlProvider.

        public class MySqlInstanceControlProvider : InstanceControlProvider
        {
        }
    
  5. Implementare il metodo Initialize. Questo metodo accetta un contenitore delle proprietà che corrisponda alle informazioni di configurazione specificate nel file di configurazione. I dati presenti in tale contenitore vengono utilizzati per costruire il provider. Il metodo Initialize viene chiamato prima dei metodi CreateInstanceControl o UniqueProviderIdentifier.

    Nota

    Negli scenari remoti, la raccolta nome-valore contiene un elemento denominato “EnableServiceModelMetadata”. Il provider può scegliere di ignorare e rimuovere questo parametro prima di richiamare il metodo base.Initialize. Questa proprietà in genere viene utilizzata per determinare se richiamare SetMetadata(“ServiceModel”, true) sull'oggetto Microsoft.Web.Administration.ServerManager.

    
            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. Implementare il metodo CreateInstanceControl della classe InstanceControlProvider per restituire un oggetto InstanceControl personalizzato che sarà utilizzato dal cliente per accedere a un oggetto CommandSend o CommandReceive.

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

    Nota

    Per informazioni sull'implementazione del tipo di oggetto MySqlInstanceControl, vedere la sezione successiva.

  7. Implementare il metodo UniqueProviderIdentifier. L'ID provider univoco restituito da questo metodo consente di determinare se diversi oggetti provider conducono allo stesso archivio sottostante.

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

Implementazione dell'oggetto InstanceControl

Nella procedura seguente viene descritto come creare un tipo di oggetto InstanceControl personalizzato.

  1. Creare una classe derivata dalla classe InstanceControl.

        public class MySqlInstanceControl : InstanceControl
        {
            readonly string connectionString;
             public MySqlInstanceControl(string connectionString)
             {
                 this.connectionString = connectionString;
             }
        }
    
  2. Implementare la proprietà CommandReceive. Il metodo della funzione di accesso Get della proprietà CommandReceive restituirà un oggetto CommandReceive. I client richiamano i metodi su questo oggetto per ricevere comandi in modo asincrono dalla coda dei comandi.

            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. Implementare la proprietà CommandSend per restituire un oggetto CommandSend dal metodo della funzione di accesso Get. Il metodo Get della proprietà CommandSend restituirà un oggetto CommandSend. I client richiamano i metodi di questo oggetto per inviare comandi in modo asincrono alla coda dei comandi.

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

    Il client utilizza questi due oggetti per inviare comandi alla coda dei comandi (accodamento) e ricevere comandi dalla stessa (annullamento dell'accodamento). Ad esempio, un controllo delle istanze cmdlet accoda un comando alla coda dei comandi mediante l'utilizzo dell'oggetto CommandSend e il servizio Gestione flussi di lavoro rimuove il comando dalla coda dei comandi mediante l'utilizzo dell'oggetto CommandReceive. In alcune circostanze, ad esempio quando viene eseguito il cmdlet Remove-ASAppServiceInstance, l'archivio stesso elabora il comando per rimuovere l'istanza dall'archiviazione istanza.

    Nota

    Per informazioni sull'implementazione dei tipi MySqlCommandSend e MySqlCommandReceive, vedere le sezioni successive.

Implementazione dell'oggetto CommandSend

Per creare un tipo di oggetto CommandSend personalizzato:

  • Creare una classe derivata dalla classe CommandSend e implementare i metodi BeginTrySend e 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();
            }
        }
    

Implementazione dell'oggetto CommandReceive

Per creare un tipo di oggetto CommandReceive personalizzato:

  • Creare una classe derivata dalla classe CommandReceive e implementare i metodi BeginTryReceive e 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();
            }
        }
    

    Nota

    Per informazioni sull'implementazione della classe MySqlReceivedInstanceCommand, vedere la sezione successiva.

Implementazione dell'oggetto ReceivedInstanceCommand

Per creare un tipo di oggetto ReceivedInstanceCommand personalizzato:

  • Creare una classe derivata dalla classe ReceivedInstanceCommand e implementare la proprietà InstanceCommandContext.

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

    Nota

    Per informazioni sull'implementazione del tipo di oggetto MySqlInstanceCommandContext, vedere la sezione successiva.

Implementazione dell'oggetto InstanceCommandContext

Per creare un tipo di oggetto InstanceCommandContext personalizzato:

  • Creare una classe derivata dalla classe InstanceCommandContext e implementare i metodi BeginComplete, EndComplete, BeginAbandon e EndAbandon.

    I client richiamano il metodo BeginComplete sull'oggetto InstanceCommandContext per segnalare il completamento dell'esecuzione del comando. Il provider di controllo, quindi, rimuoverà il comando dalla coda dei comandi. Il servizio Gestione flussi di lavoro richiama il metodo se l'esecuzione del comando viene correttamente completata.

    I client richiamano il metodo BeginAbandon sull'oggetto InstanceCommandContext per segnalare il non completamento dell'esecuzione del comando. Il provider del controllo delle istanze è responsabile della gestione del comando. Ad esempio, un provider di controllo potrebbe riprovare ad eseguire il comando per un determinato numero di volte prima di rimuoverlo dalla coda dei comandi. Il servizio Gestione flussi di lavoro richiama il metodo se l'esecuzione del comando non viene correttamente completata.

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

Vedere anche

Concetti

Procedura: sviluppare un provider di archiviazione istanza
Procedura: sviluppare un provider di query di istanza
Procedura: configurare provider di archiviazione, query e controllo di istanza
Provider di archiviazione, query e controllo di istanza

  2012-03-05