作法:開發執行個體控制提供者
下列程序提供建立自訂執行個體控制提供者的步驟。
建立類別庫專案。
新增對 Microsoft.ApplicationServer.StoreManagement 的參考。此外,新增對 System.Configuration 組件的參考以編譯本主題中的範例程式碼。
在來源檔案的開頭加入下列陳述式。
using Microsoft.ApplicationServer.StoreManagement.Control; using Microsoft.ApplicationServer.StoreManagement.Control; using System.Data.SqlClient; using System.Collections.Specialized; using System.Threading; using System.Data;
為執行個體控制提供者建立衍生自 InstanceControlProvider 類別的類別。
public class MySqlInstanceControlProvider : InstanceControlProvider { }
實作 Initialize 方法。此方法接受對應至組態檔中指定之組態資訊的屬性包。系統會使用此屬性包中的資料來建構提供者。在呼叫 CreateInstanceControl 或 UniqueProviderIdentifier 方法之前,先呼叫 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); }
實作 InstanceControlProvider 類別的 CreateInstanceControl 方法以傳回自訂 InstanceControl 物件,供用戶端用來存取 CommandSend 物件或 CommandReceive 物件。
public override InstanceControl CreateInstanceControl() { SqlConnectionStringBuilder connectionStringBuilder = new SqlConnectionStringBuilder(this.ConnectionString); connectionStringBuilder.AsynchronousProcessing = true; return new MySqlInstanceControl(connectionStringBuilder.ConnectionString); }
注意
如需 MySqlInstanceControl 類型實作的詳細資訊,請參閱下一節。
實作 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 類型的步驟。
建立衍生自 InstanceControl 類別的類別。
public class MySqlInstanceControl : InstanceControl { readonly string connectionString; public MySqlInstanceControl(string connectionString) { this.connectionString = connectionString; } }
實作 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; } }
實作 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 時),儲存區本身會處理命令,以將執行個體從執行個體儲存區移除。
注意
如需有關 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 方法。
用戶端會針對 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