應用程式運行時配置透過 System.Configuration.ConfigManager 讀取 XML 配置檔。靜態 Get 方法回傳集合,列舉取得單一屬性。除主配置檔外,需建立中繼資料結構定義檔(.xms),並在伺服器 Machine.config 註冊:
<?xml version="1.0"?>
<MetaData xmlns="x-schema:CatMeta.xms">
<DatabaseMeta InternalName="MessageService">
<ServerWiring Interceptor="Core_XMLInterceptor"/>
<Collection InternalName="Process" PublicName="ProcessList" PublicRowName="ProcessDefinition" SchemaGeneratorFlags="EMITXMLSCHEMA">
<Property InternalName="ProcessName" Type="String" MetaFlags="PRIMARYKEY"/>
<Property InternalName="ProcessDesc" Type="String"/>
<Property InternalName="ProcessType" Type="Int32" DefaultValue="RoundRobin">
<Enum InternalName="RoundRobin" Value="0"/>
<Enum InternalName="AppSpecific" Value="1"/>
<Enum InternalName="Assembly" Value="2"/>
</Property>
<Property InternalName="ProcessThreads" Type="Int32" DefaultValue="1"/>
<Property InternalName="InputQueue" Type="String"/>
<Property InternalName="ErrorQueue" Type="String"/>
<Property InternalName="OutputName" Type="String"/>
<QueryMeta InternalName="All" MetaFlags="ALL"/>
<QueryMeta InternalName="QueryByFile" CellName="__FILE" Operator="EQUAL"/>
</Collection>
<Collection InternalName="Output" PublicName="OutputList" PublicRowName="OutputDefinition" SchemaGeneratorFlags="EMITXMLSCHEMA">
<Property InternalName="ProcessName" Type="String" MetaFlags="PRIMARYKEY"/>
<Property InternalName="OutputName" Type="String" MetaFlags="PRIMARYKEY"/>
<QueryMeta InternalName="All" MetaFlags="ALL"/>
<QueryMeta InternalName="QueryByFile" CellName="__FILE" Operator="EQUAL"/>
</Collection>
<RelationMeta PrimaryTable="Process" PrimaryColumns="ProcessName" ForeignTable="Output" ForeignColumns="ProcessName" MetaFlags="USECONTAINMENT"/>
</DatabaseMeta>
</MetaData>
private Hashtable htWorkers = new Hashtable();
IConfigCollection cWorkers = ConfigManager.Get("ProcessList", new AppDomainSelector());
foreach (IConfigItem ciWorker in cWorkers) {
WorkerFormatter sf = new WorkerFormatter();
sf.ProcessName = (string)ciWorker["ProcessName"];
sf.ProcessDesc = (string)ciWorker["ProcessDesc"];
sf.NumberThreads = (int)ciWorker["ProcessThreads"];
sf.InputQueue = (string)ciWorker["InputQueue"];
sf.ErrorQueue = (string)ciWorker["ErrorQueue"];
switch ((int)ciWorker["ProcessType"]) {
case 0: sf.ProcessType = WorkerFormatter.SFProcessType.ProcessRoundRobin; break;
case 1: sf.ProcessType = WorkerFormatter.SFProcessType.ProcessAppSpecific; break;
case 2: sf.ProcessType = WorkerFormatter.SFProcessType.ProcessAssembly; break;
default: throw new Exception("Unknown Processing Type");
}
string procName = (string)ciWorker["ProcessName"];
if (htWorkers.ContainsKey(procName))
throw new ArgumentException("Process Name Must be Unique: " + procName);
htWorkers.Add(procName, new CWorker(sf));
}
Hashtable 以 ProcessName 為鍵,支援快速查找與列舉。WorkerFormatter 結構體封裝運行時參數(值型別,避免參考語意副作用)。