共用方式為


作法:開發執行個體控制提供者

下列程序提供建立自訂執行個體控制提供者的步驟。

  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 方法。此方法接受對應至組態檔中指定之組態資訊的屬性包。系統會使用此屬性包中的資料來建構提供者。在呼叫 CreateInstanceControlUniqueProviderIdentifier 方法之前,先呼叫 Initialize 方法。

    注意

    在遠端處理案例中,名稱-值集合會包含名為 “EnableServiceModelMetadata” 的項目。提供者可選擇在叫用 base.Initialize 方法之前忽略並移除此參數。此屬性通常是用來決定是否要叫用 Microsoft.Web.Administration.ServerManager 物件上的 SetMetadata(“ServiceModel”, true)。

    
            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. 實作 InstanceControlProvider 類別的 CreateInstanceControl 方法以傳回自訂 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 屬性。CommandReceive 屬性的 Get 存取子方法應傳回 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 屬性,並利用 Get 存取子方法傳回自訂的 CommandSend 物件。CommandSend 屬性的 Get 方法應傳回 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;
                }
            }
    

    用戶端使用這兩個物件來傳送命令至命令佇列 (放入佇列),以及接收來自命令佇列的命令 (從佇列移出)。例如,執行個體控制 Cmdlet 使用 CommandSend 物件將命令放入命令佇列,而「工作流程管理服務」(WMS) 使用 CommandReceive 物件將命令從命令佇列移出。在某些情況下 (例如執行 Remove-ASAppServiceInstance Cmdlet 時),儲存區本身會處理命令,以將執行個體從執行個體儲存區移除。

    注意

    如需有關 MySqlCommandSendMySqlCommandReceive 類型實作的詳細資訊,請參閱下一節。

實作 CommandSend

建立自訂的 CommandSend 類型:

  • 建立衍生自 CommandSend 類別的類別,並實作 BeginTrySendEndTrySend 方法。

        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 類別的類別,並實作 BeginTryReceiveEndTryReceive 方法。

        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 類別的類別,並實作 BeginCompleteEndCompleteBeginAbandonEndAbandon 方法。

    用戶端會針對 InstanceCommandContext 物件叫用 BeginComplete 方法,以通知命令已成功執行。控制提供者應從命令佇列移除命令。如果命令成功執行,WMS 會叫用此方法。

    用戶端會針對 InstanceCommandContext 物件叫用 BeginAbandon 方法,以通知命令執行失敗。執行個體控制提供者會決定如何處理命令。例如,控制提供者可重試命令數次,然後再從命令佇列移除命令。如果命令執行失敗,WMS 會叫用此方法。

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

另請參閱

概念

作法:開發執行個體儲存提供者
作法:開發執行個體查詢提供者
作法:設定執行個體儲存、查詢與控制提供者
執行個體儲存、查詢與控制提供者

  2012-03-05