Инструкция по разработке поставщика управления экземплярами

В следующей пошаговой процедуре приведены действия по созданию пользовательского поставщика управления экземплярами.

  1. Создайте проект библиотеки классов.

  2. Добавьте ссылку на Microsoft.ApplicationServer.StoreManagement. Кроме того, добавьте ссылку на сборку System.Configuration, чтобы скомпилировать код примера, приведенный в этом разделе.

  3. Добавьте указанную ниже инструкцию в самое начало исходного файла.

    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. Создайте класс для поставщика управления экземплярами, производного от класса InstanceControlProvider.

        public class MySqlInstanceControlProvider : InstanceControlProvider
        {
        }
    
  5. Реализуйте метод Initialize. Этот метод принимает контейнер свойств, соответствующий данным, указанным в файле конфигурации. Данные в этом контейнере свойств используются для создания поставщика. Метод Initialize вызывается до метода CreateInstanceControl или UniqueProviderIdentifier.

    Примечание

    В удаленных сценариях коллекция имя-значение будет содержать элемент EnableServiceModelMetadata. Поставщик может игнорировать или удалить этот параметр до вызова метода base.Initialize. Как правило, это свойство используется для определения, следует ли вызывать SetMetadata(“ServiceModel”, true) для объекта 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. Реализуйте метод CreateInstanceControl класса InstanceControlProvider для возвращения пользовательского объекта InstanceControl, который будет использоваться клиентом для доступа к объекту CommandSend или объекту CommandReceive.

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

    Примечание

    Реализация типа MySqlInstanceControl показана в следующем разделе.

  7. Реализуйте метод UniqueProviderIdentifier. Уникальный идентификатор поставщика, возвращаемый этим методом, используется для определения, будут ли различные объекты поставщика разрешаться в одно базовое хранилище.

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

Реализация InstanceControl

В следующей пошаговой процедуре приведены действия по созданию пользовательского типа InstanceControl.

  1. Создайте класс, производный от класса InstanceControl.

        public class MySqlInstanceControl : InstanceControl
        {
            readonly string connectionString;
             public MySqlInstanceControl(string connectionString)
             {
                 this.connectionString = connectionString;
             }
        }
    
  2. Реализуйте свойство CommandReceive. Метод доступа Get свойства CommandReceive должен возвращать объект CommandReceive. Клиент вызывает методы для этого объекта, чтобы асинхронно получать команды из очереди.

            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. Реализуйте свойство CommandSend и возвратите пользовательский объект CommandSend из метода доступа Get. Метод доступа Get свойства CommandSend должен возвращать объект CommandSend. Клиент вызывает методы для этого объекта, чтобы асинхронно отправлять команды в очередь.

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

    Клиент использует эти два объекта для отправки команд в очередь (постановка) и получения команд из очереди (извлечение). Например, командлет управления экземплярами отправляет в очередь команду с помощью объекта CommandSend, а служба управления рабочими процессами извлекает команду из очереди с помощью объекта CommandReceive. В некоторых случаях, например при выполнении командлета Remove-ASAppServiceInstance, само хранилище обрабатывает команду для удаления экземпляра из хранилища экземпляров.

    Примечание

    Реализацию типов MySqlCommandSend и MySqlCommandReceive см. в следующих разделах.

Реализация CommandSend

Чтобы создать пользовательский тип CommandSend, выполните следующие действия:

  • Создайте класс, производный от класса CommandSend, и реализуйте методы BeginTrySend и 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();
            }
        }
    

Реализация CommandReceive

Чтобы создать пользовательский тип CommandReceive, выполните следующие действия:

  • Создайте класс, производный от класса CommandReceive, и реализуйте методы BeginTryReceive и 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();
            }
        }
    

    Примечание

    Реализацию класса MySqlReceivedInstanceCommand см. в следующем разделе.

Реализация ReceivedInstanceCommand

Чтобы создать пользовательский тип ReceivedInstanceCommand, выполните следующие действия:

  • Создайте класс, производный от класса ReceivedInstanceCommand, и реализуйте свойство 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;
                }
            }
        }
    

    Примечание

    Реализацию класса MySqlInstanceCommandContext см. в следующем разделе.

Реализация InstanceCommandContext

Чтобы создать пользовательский тип InstanceCommandContext, выполните следующие действия:

  • Создайте класс, производный от InstanceCommandContext, и реализуйте методы BeginComplete, EndComplete, BeginAbandon и EndAbandon.

    Клиент вызывает метод BeginComplete для объекта InstanceCommandContext, чтобы уведомить об успешном выполнении команды. Затем поставщик управления должен удалить команду из очереди команд. Служба управления рабочими процессами вызывает этот метод, если выполнение команды завершается успешно.

    Клиент вызывает метод BeginAbandon для объекта InstanceCommandContext, чтобы уведомить о неудачно завершившемся выполнении команды. Дальнейшие действия с командой зависят от поставщика управления экземплярами. Например, поставщик управления может повторить выполнение команды определенное количество раз, прежде чем удалить команду из очереди. Служба управления рабочими процессами вызывает этот метод, если выполнение команды завершается со сбоем.

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

См. также

Основные понятия

Инструкция по разработке поставщика хранилища экземпляров
Инструкция по разработке поставщика запросов экземпляров
Инструкция по настройке поставщиков хранилищ экземпляров, запросов и управления
Поставщики хранилищ экземпляров, запросов и управления

  2011-12-05