Partilhar via


Como: desenvolver provedores de controle de instância

O procedimento a seguir fornece etapas para criar um provedor de controle de instância personalizado.

  1. Crie um projeto Biblioteca de Classes.

  2. Adicione uma referência a Microsoft.ApplicationServer.StoreManagement. Além disso, adicione uma referência ao assembly System.Configuration para configurar o código de exemplo neste tópico.

  3. Adicione a seguinte instrução no início do arquivo de origem.

    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. Crie uma classe para o provedor de controle de instância que derive da classe InstanceControlProvider.

        public class MySqlInstanceControlProvider : InstanceControlProvider
        {
        }
    
  5. Implemente o método Initialize. Esse método aceita um recipiente de propriedades que corresponde às informações de configuração especificadas no arquivo de configuração. Os dados nesse recipiente de propriedades são usados para construir o provedor. O método Initialize é chamado antes do método CreateInstanceControl ou UniqueProviderIdentifier ser chamado.

    Dica

    Em cenários remotos, o conjunto nome-valor conterá um item denominado “EnableServiceModelMetadata”. O provedor pode optar por ignorar e remover esse parâmetros antes de chamar o método base.Initialize. Esta propriedade geralmente é usada para determinar se SetMetadata(“ServiceModel”, true) deve ser chamado no objeto 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. Implemente o método CreateInstanceControl da classe InstanceControlProvider para retornar um objeto InstanceControl personalizado, que o cliente usará para acessar um objeto CommandSend ou CommandReceive.

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

    Dica

    Consulte a próxima seção para a implementação do tipo MySqlInstanceControl.

  7. Implemente o método UniqueProviderIdentifier. A ID do provedor exclusiva que esse método retorna é usada para determinar se objetos de provedor diferentes são usados para o mesmo repositório subjacente.

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

Implementando o InstanceControl

O procedimento a seguir fornece etapas para criar um tipo InstanceControl personalizado.

  1. Crie uma classe que derive da classe InstanceControl.

        public class MySqlInstanceControl : InstanceControl
        {
            readonly string connectionString;
             public MySqlInstanceControl(string connectionString)
             {
                 this.connectionString = connectionString;
             }
        }
    
  2. Implemente a propriedade CommandReceive. O método de acessador Get da propriedade CommandReceive deve retornar um objeto CommandReceive. Um cliente chama os métodos desse objeto para receber assincronamente os comandos da fila.

            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. Implemente a propriedade CommandSend e retorne um objeto CommandSend personalizado do método de acessador Get. O método Get da propriedade CommandSend deve retornar um objeto CommandSend. Um cliente chama os métodos desse objeto para enviar assincronamente comandos à fila.

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

    O cliente usa esses dois objetos para enviar comandos à filha (enfileirar) e remover comandos da fila (tirar da fila). Por exemplo, um cmdlet de controle de instância coloca um comando na fila usando o objeto CommandSend e o WMS (Serviço Gerenciamento de Fluxo de Trabalho) tira o comando da fila usando o objeto CommandReceive. Em algumas circunstâncias, como quando o cmdlet Remove-ASAppServiceInstance é executado, o próprio repositório processa o comando para remover a instância do repositório de instância.

    Dica

    Consulte as seções a seguir para obter implementações dos tipos MySqlCommandSend e MySqlCommandReceive.

Implementando o CommandSend

Para criar um tipo CommandSend personalizado:

  • Crie uma classe que derive da classe CommandSend e implemente os métodos 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();
            }
        }
    

Implementando o CommandReceive

Para criar um tipo CommandReceive personalizado:

  • Crie uma classe que derive da classe CommandReceive e implemente os métodos 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();
            }
        }
    

    Dica

    Consulte a seguinte seção para implementação da classe MySqlReceivedInstanceCommand.

Implementando o ReceivedInstanceCommand

Para criar um tipo ReceivedInstanceCommand personalizado:

  • Crie uma classe que derive da classe ReceivedInstanceCommand e implemente a propriedade 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;
                }
            }
        }
    

    Dica

    Consulte a seguinte seção para implementação do tipo MySqlInstanceCommandContext.

Implementando o InstanceCommandContext

Para criar um tipo InstanceCommandContext personalizado:

  • Crie uma classe que derive da classe InstanceCommandContext e implemente os métodos BeginComplete, EndComplete, BeginAbandon e EndAbandon.

    Um cliente chama o método BeginComplete no objeto InstanceCommandContext para notificar que a execução do comando foi bem-sucedida. Em seguida, o provedor de controle deve remover o comando da fila. O WMS chamará esse método se a execução do comando for bem-sucedida.

    Um cliente chama o método BeginAbandon no objeto InstanceCommandContext para notificar a falha na execução do comando. É opção do provedor de controle da instância decidir o que fazer com o comando. Por exemplo, um provedor de controle poderá repetir o comando um número específico de vezes antes de remover o comando da fila. O WMS chamará esse método se a execução do comando falhar.

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

Consulte também

Conceitos

Como: desenvolver provedores de repositório de instância
Como: desenvolver provedores de consulta de instância
Como: configurar repositório de instância, consulta e Provedores de controle
Repositório de instância, Consulta e Provedores de controle

  2011-12-05