Procédure de développement d'un fournisseur de contrôle des instances
La procédure suivante décrit la création d'un fournisseur de contrôle d'instances personnalisé.
Créez un projet Class Library.
Ajoutez une référence à Microsoft.ApplicationServer.StoreManagement. Ajoutez également une référence à l'assembly System.Configuration pour compiler l'exemple de code dans cette rubrique.
Ajoutez les instructions suivantes au début du fichier source.
using Microsoft.ApplicationServer.StoreManagement.Control; using Microsoft.ApplicationServer.StoreManagement.Control; using System.Data.SqlClient; using System.Collections.Specialized; using System.Threading; using System.Data;
Créez une classe pour le fournisseur de contrôle d'instances dérivé de la classe InstanceControlProvider.
public class MySqlInstanceControlProvider : InstanceControlProvider { }
Implémentez la méthode Initialize. Cette méthode accepte un jeu de propriétés correspondant aux informations de configuration spécifiées dans le fichier de configuration. Les données dans le jeu de propriétés sont utilisées pour créer le fournisseur. La méthode Initialize est appelée avant la méthode CreateInstanceControl ou UniqueProviderIdentifier.
Notes
Dans les scénarios de communication à distance, l'ensemble nom-valeur contient un élément nommé « EnableServiceModelMetadata ». Le fournisseur peut ignorer et supprimer ce paramètre avant d'appeler la méthode base.Initialize. Cette propriété sert généralement à déterminer s'il faut appeler SetMetadata(“ServiceModel”, true) sur l'objet 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); }
Implémentez la méthode CreateInstanceControl de la classe InstanceControlProvider pour renvoyer un objet InstanceControl personnalisé, que le client utilise pour accéder à l'objet CommandSend ou à l'objet CommandReceive.
public override InstanceControl CreateInstanceControl() { SqlConnectionStringBuilder connectionStringBuilder = new SqlConnectionStringBuilder(this.ConnectionString); connectionStringBuilder.AsynchronousProcessing = true; return new MySqlInstanceControl(connectionStringBuilder.ConnectionString); }
Notes
Consultez la section suivante pour l'implémentation du type MySqlInstanceControl.
Implémentez la méthode UniqueProviderIdentifier. L'ID de fournisseur unique que renvoie cette méthode permet de déterminer si différents objets de fournisseur sont résolus en un magasin sous-jacent identique.
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(); } } }
Implémentation du type InstanceControl
La procédure suivante détaille les étapes de création d'un type InstanceControl personnalisé.
Créez une classe dérivée de la classe InstanceControl.
public class MySqlInstanceControl : InstanceControl { readonly string connectionString; public MySqlInstanceControl(string connectionString) { this.connectionString = connectionString; } }
Implémentez la propriété CommandReceive. La méthode d'accesseur Get de la propriété CommandReceive doit renvoyer un objet CommandReceive. Un client appelle des méthodes sur cet objet pour recevoir des commandes de la file d'attente de commandes de façon asynchrone.
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; } }
Implémentez la propriété CommandSend et renvoyez un objet CommandSend personnalisé depuis la méthode d'accesseur Get. La méthode Get de la propriété CommandSend doit renvoyer un objet CommandSend. Un client appelle des méthodes sur cet objet pour envoyer des commandes de la file d'attente de commandes de façon asynchrone.
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; } }
Le client utilise ces deux objets pour placer des commandes dans la file d'attente de commandes et en recevoir de cette même file d'attente. Par exemple, une cmdlet de contrôle des instances place une commande dans la file d'attente de commandes à l'aide de l'objet CommandSend et le service de gestion du flux de travail (WMS, Workflow Management Service) enlève la commande de la file d'attente de commandes à l'aide de l'objet CommandReceive. Dans certaines circonstances telles que l'exécution de la cmdlet Remove-ASAppServiceInstance, le magasin traite lui-même la commande pour supprimer l'instance du magasin d'instances.
Notes
Consultez les sections suivantes pour les implémentations des types MySqlCommandSend et MySqlCommandReceive.
Implémentation du type CommandSend
Pour créer un type CommandSend personnalisé, procédez comme suit.
Créez une classe dérivée de la classe CommandSend et implémentez les méthodes BeginTrySend et 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(); } }
Implémentation du type CommandReceive
Pour créer un type CommandReceive personnalisé, procédez comme suit.
Créez une classe dérivée de la classe CommandReceive et implémentez les méthodes BeginTryReceive et 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(); } }
Notes
Consultez la section suivante pour l'implémentation de la classe MySqlReceivedInstanceCommand.
Implémentation du type ReceivedInstanceCommand
Pour créer un type ReceivedInstanceCommand personnalisé, procédez comme suit.
Créez une classe dérivée de la classe ReceivedInstanceCommand et implémentez la propriété 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; } } }
Notes
Consultez la section suivante pour l'implémentation du type MySqlReceivedInstanceCommand.
Implémentation du type InstanceCommandContext
Pour créer un type InstanceCommandContext personnalisé, procédez comme suit.
Créez une classe dérivée de la classe InstanceCommandContext et implémentez les méthodes BeginComplete, EndComplete, BeginAbandon et EndAbandon.
Un client appelle la méthode BeginComplete sur l'objet InstanceCommandContext pour notifier la réussite de l'exécution de la commande. Le fournisseur de contrôle doit ensuite supprimer la commande de la file d'attente de commandes. Le service WMS appelle cette méthode en cas de succès de l'exécution de la commande.
Un client appelle la méthode BeginAbandon sur l'objet InstanceCommandContext pour notifier l'échec de l'exécution de la commande. Il revient au fournisseur de contrôle des instances de décider de l'action à effectuer en relation avec la commande. Par exemple, un fournisseur de contrôle peut réessayer la commande un nombre de fois spécifique avant de la supprimer de la file d'attente de commandes. Le service WMS appelle cette méthode en cas d'échec de l'exécution de la commande.
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(); } }
Voir aussi
Concepts
Procédure de développement d'un fournisseur de magasin d'instances
Procédure de développement d'un fournisseur de requête d'instances
Procédure de configuration de fournisseurs de magasin d'instances, de requête et de contrôle
Fournisseurs de magasin d'instances, de requête et de contrôle
2012-03-05