Cómo Desarrollar un proveedor de control de instancias
En el procedimiento siguiente se proporcionan los pasos para crear un proveedor de control de instancias personalizado.
Cree el proyecto Biblioteca de clases.
Agregue una referencia a Microsoft.ApplicationServer.StoreManagement. Además, agregue una referencia al ensamblado System.Configuration para compilar el código de ejemplo incluido en este tema.
Agregue la siguiente sentencia al principio del archivo de origen.
using Microsoft.ApplicationServer.StoreManagement.Control; using Microsoft.ApplicationServer.StoreManagement.Control; using System.Data.SqlClient; using System.Collections.Specialized; using System.Threading; using System.Data;
Cree una clase para el proveedor de control de instancias que se derive de la clase InstanceControlProvider.
public class MySqlInstanceControlProvider : InstanceControlProvider { }
Implemente el método Initialize. Este método acepta un contenedor de propiedades que corresponde a la información de configuración especificada en el archivo de configuración. Los datos de este contenedor de propiedades se usan para construir el proveedor. El método Initialize se llama antes de que se llamen los métodos CreateInstanceControl o UniqueProviderIdentifier.
Nota
En escenarios remotos, la recopilación de nombres y valores contendría un elemento denominado “EnableServiceModelMetadata”. El proveedor puede optar por pasar por alto y quitar este parámetro antes de invocar el método base.Initialize. Esta propiedad suele usarse para determinar si se debe invocar SetMetadata(“ServiceModel”, true) en el 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 el método CreateInstanceControl de la clase InstanceControlProvider para devolver un objeto InstanceControl personalizado, que el cliente usará para obtener acceso a un objeto CommandSend o a un objeto CommandReceive.
public override InstanceControl CreateInstanceControl() { SqlConnectionStringBuilder connectionStringBuilder = new SqlConnectionStringBuilder(this.ConnectionString); connectionStringBuilder.AsynchronousProcessing = true; return new MySqlInstanceControl(connectionStringBuilder.ConnectionString); }
Nota
Consulte la siguiente sección para ver la implementación del tipo MySqlInstanceControl.
Implemente el método UniqueProviderIdentifier. El identificador de proveedor exclusivo que este método devuelve se usa para determinar si los diferentes objetos de proveedor se resuelven en el mismo almacén subyacente.
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(); } } }
Implementación de InstanceControl
En el procedimiento siguiente se proporcionan los pasos para crear un tipo InstanceControl personalizado.
Cree una clase que se derive de la clase InstanceControl.
public class MySqlInstanceControl : InstanceControl { readonly string connectionString; public MySqlInstanceControl(string connectionString) { this.connectionString = connectionString; } }
Implemente la propiedad CommandReceive. El método del descriptor de acceso Get de la propiedad CommandReceive debe devolver un objeto CommandReceive. Un cliente invoca métodos en este objeto para recibir de forma asíncrona comandos de la cola de comandos.
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 la propiedad CommandSend y devuelva un objeto CommandSend personalizado del método del descriptor de acceso Get. El método Get de la propiedad CommandSend debe devolver un objeto CommandSend. Un cliente invoca métodos de este objeto para enviar de forma asíncrona comandos a la cola de comandos.
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; } }
El cliente usa estos dos objetos para enviar comandos a la cola de comandos (poner en cola) y recibir comandos de la cola de comandos (quitar de la cola). Por ejemplo, un cmdlet de control de instancias pone un comando en la cola de comandos mediante el objeto CommandSend y el Servicio de administración de flujos de trabajo (WMS) quita el comando de la cola de comandos mediante el objeto CommandReceive. En algunas circunstancias, como cuando se ejecuta el cmdlet Remove-ASAppServiceInstance, el propio almacén procesa el comando para quitar la instancia del almacén de instancias.
Nota
Consulte las secciones siguientes para ver las implementaciones de los tipos MySqlCommandSend y MySqlCommandReceive.
Implementación de CommandSend
Para crear un tipo CommandSend personalizado:
Cree una clase que se derive de la clase CommandSend e implemente los métodos BeginTrySend y 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(); } }
Implementación de CommandReceive
Para crear un tipo CommandReceive personalizado:
Cree una clase que se derive de la clase CommandReceive e implemente los métodos BeginTryReceive y 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
Consulte la siguiente sección para la implementación de la clase MySqlReceivedInstanceCommand.
Implementación de ReceivedInstanceCommand
Para crear un tipo ReceivedInstanceCommand personalizado:
Cree una clase que se derive de la clase ReceivedInstanceCommand e implemente la propiedad 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
Consulte la siguiente sección para la implementación del tipo MySqlInstanceCommandContext.
Implementación de InstanceCommandContext
Para crear un tipo de InstanceCommandContext personalizado:
Cree una clase que se derive de la clase InstanceCommandContext e implemente los métodos BeginComplete, EndComplete, BeginAbandon y EndAbandon.
Un cliente invoca el método BeginComplete en el objeto InstanceCommandContext para notificar que el comando se ejecutó correctamente. A continuación, el proveedor de control debe quitar el comando de la cola de comandos. WMS invoca este método si la ejecución del comando es correcta.
Un cliente invoca el método BeginAbandon en el objeto InstanceCommandContext para notificar que el comando no se ejecutó correctamente. Corresponde al proveedor de control de instancias decidir lo que se debe hacer con el comando. Por ejemplo, un proveedor de control puede reintentar el comando un número de veces específico antes de quitarlo de la cola de comandos. WMS invoca este método si la ejecución del comando no es correcta.
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(); } }
Vea también
Conceptos
Cómo Desarrollar un proveedor de almacenes de instancias
Cómo Desarrollar un proveedor de consultas de instancias
Cómo configurar proveedores de almacenes de instancias, consultas y control
Proveedores de almacenes de instancias, consultas y control
2011-12-05