Como: Desenvolver provedores de controle de instância
O procedimento a seguir fornece etapas para criar um provedor de controle de instância personalizado.
Crie um projeto de Biblioteca de Classe.
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.
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;
Crie uma classe para o provedor de controle de instância que derive da classe InstanceControlProvider.
public class MySqlInstanceControlProvider : InstanceControlProvider { }
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 neste 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, a coleção nome-valor pode conter um item denominado “EnableServiceModelMetadata”. O provedor pode optar por ignorar e remover esse parâmetro antes de invocar o método base.Initialize. Normalmente, essa propriedade é utilizada para determinar se SetMetadata(“ServiceModel”, true) deve ser invocado 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); }
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.
Implemente o método UniqueProviderIdentifier. A ID exclusiva do provedor que esse método retorna é usada para determinar se objetos diferentes do provedor são resolvidos no 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.
Crie uma classe que derive da classe InstanceControl.
public class MySqlInstanceControl : InstanceControl { readonly string connectionString; public MySqlInstanceControl(string connectionString) { this.connectionString = connectionString; } }
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; } }
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 provedores de repositório de instância, consulta e controle
Provedores de repositório de instância, consulta e controle
2012-03-05