Enterprise Library 自訂控制介面方法

來源:互聯網
上載者:User

1. 概述

上篇,我對 Enterprise Library 自訂應用程式塊的運行時編寫進行了描述,在此我們將學習如何編寫自訂應用程式塊的設計時,以支援 Enterprise Library 配置控制台的使用。
編寫設計時包括四個部分:定義配置所對應的節點類、配置節點與設定檔 XML 間的序列化和還原序列化類、Enterprise Library 配置控制台 UI 註冊類和配置控制台的執行註冊。

2. 定義配置節點

由於應用程式設定檔是基於 XML 的,因此它們天生便具有階層。配置控制台將此模型化為一個由節點群組成的樹。運行時組件中的每個配置元素必須由一個設計時節點類來表示,該節點類為配置類提供了額外的設計時行為。
根據應用程式塊的源 Scheme ,我們可以得出下列的對應關係,其中第一列為配置元素,第二列為配置類,第三列為配置節點類:

<plugInConfiguration>         -->             PlugInLoaderSettings                           -->         PlugInLoaderSettingsNode
<plugInProviders>              -->             PlugInLoaderSettings.PlugInProviders      -->         PlugInProviderCollectionNode
<add>                             -->             PlugInProviderData                              -->         PlugInProviderNode

以上三個配置結點類都繼承自 Microsoft.Practices.EnterpriseLibrary.Configuration.Design 命名空間中的 ConfigurationNode 類。
另外,針對在上篇中所實現的二個具體提供者的配置類:InjectionPlugInProviderData 和 NaivePlugInProviderData ,也實現了繼承自 PlugInProviderNode 的相應的配置節點類 InjectionPlugInProviderNode 和 NaivePlugInProviderNode  。
因為這些配置節點類僅是普通的設計時組件類,所以在此不再詳述。

3. 配置節點與設定檔 XML 間的序列化和還原序列化

在配置控制台中修改節點的資訊後,必須通過序列化成 XML 才能儲存到設定檔中,同樣,設定檔中的 XML 配置資料必須通過還原序列化才能形成 UI 上的節點。
在此,序列化我們可以通過一個 PlugInLoaderSettingsBuilder 類即可實現,而還原序列化需要 PlugInLoaderSettingsNode 所對應的 PlugInLoaderSettingsNodeBuilder 和 PlugInProviderCollectionNode 所對應的 PlugInProviderCollectionNodeBuilder 類來實現,其中反序化的二個類繼承中 Microsoft.Practices.EnterpriseLibrary.Configuration.Design 命名空間中的 NodeBuilder 類。

3.1 PlugInLoaderSettingsBuilder 類

這是 Enterprise Library 配置控制台用於序列化配置資料為 XML 的類,代碼如下:

using Microsoft.Practices.EnterpriseLibrary.Configuration.Design;
using System;

namespace PlugInLoader.Configuration.Design
{
    internal class PlugInLoaderSettingsBuilder
    {
        private PlugInLoaderSettingsNode settingsNode_;
        private IConfigurationUIHierarchy hierarchy_;

        internal PlugInLoaderSettingsBuilder(
            IServiceProvider serviceProvider,
            PlugInLoaderSettingsNode settingsNode)
        {
            this.settingsNode_ = settingsNode;
            this.hierarchy_ =
                ServiceHelper.GetCurrentHierarchy(serviceProvider);
        }

        internal PlugInLoaderSettings Build()
        {
            PlugInLoaderSettings settings = new PlugInLoaderSettings();
            this.BuildPlugInProviders(settings);
            return settings;
        }

        private void BuildPlugInProviders(PlugInLoaderSettings settings)
        {
            PlugInProviderCollectionNode providersNode =
                this.hierarchy_.FindNodeByType(this.settingsNode_,
                typeof(PlugInProviderCollectionNode))
                as PlugInProviderCollectionNode;

            if (providersNode != null)
            {
                foreach (PlugInProviderNode pipNode in providersNode.Nodes)
                {
                    settings.PlugInProviders.Add(pipNode.PlugInProviderData);
                }
            }
        }
    }
}

在此代碼中,我們需要注意一個重要的成員變數:IConfigurationUIHierarchy hierarchy_,此變數表示了 Enterprise Library 配置控制台 UI 節點的層次資訊,它在建構函式中通過 ServiceHelper.GetCurrentHierarchy 方法獲得,然後,在序列化方法 BuildPlugInProviders() 中通過 hierarchy_.FindNodeByType 方法來從層次資訊中擷取節點的資訊以構建相應的 PlugInLoaderSettings 來完成序列化。

3.2 PlugInLoaderSettingsNodeBuilder 類

PlugInLoaderSettingsNodeBuilder 類主要通過使用 PlugInProviderCollectionNodeBuilder 來完成還原序列化,在此不再解釋,請參見源碼。

3.3 PlugInProviderCollectionNodeBuilder 類

PlugInProviderCollectionNodeBuilder 類用於還原序列化 PlugInLoaderSettings.PlugInProviders ,代碼如下:

using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Configuration.Design;
using System;

namespace PlugInLoader.Configuration.Design
{
    internal class PlugInProviderCollectionNodeBuilder : NodeBuilder
    {
        private NameTypeConfigurationElementCollection<PlugInProviderData, PlugInProviderData>
            plugInProviders_;
        private PlugInProviderCollectionNode node_;

        internal PlugInProviderCollectionNodeBuilder(
            IServiceProvider serviceProvider,
            NameTypeConfigurationElementCollection<PlugInProviderData, PlugInProviderData>
            plugInProviders)
            : base(serviceProvider)
        {
            this.plugInProviders_ = plugInProviders;
        }

        internal PlugInProviderCollectionNode Build()
        {
            this.node_ = new PlugInProviderCollectionNode();
            this.plugInProviders_.ForEach(new Action<PlugInProviderData>(
                this.CreatePlugInProviderNode));
            return this.node_;
        }

        private void CreatePlugInProviderNode(PlugInProviderData pipData)
        {
            PlugInProviderNode pipNode =
                this.NodeCreationService.CreateNodeByDataType(
                pipData.GetType(), new object[] { pipData })
                as PlugInProviderNode;
            if (pipNode == null)
            {
                this.LogNodeMapError(this.node_, pipData.GetType());
            }

            this.node_.AddNode(pipNode);
        }
    }
}

在此要注意的是 Build() 方法中的 plugInProviders_.ForEach() 方法,此方法對 NameTypeConfigurationElementCollection 中的每個元素執行指定的操作。
以及 CreatePlugInProviderNode() 方法中的 this.NodeCreationService.CreateNodeByDataType() ,此方法完成真正的還原序列化以產生節點。另一個 this.LogNodeMapError() 方法用於記錄節點映射錯誤。

4. Enterprise Library 配置控制台 UI 註冊類

UI 註冊包括命令的註冊和節點映射的註冊,主要包括三個類:PlugInLoaderCommandRegistrar 類 、 PlugInLoaderNodeMapRegistrar 類和 PlugInLoaderCommandRegistrar 類。

4.1 PlugInLoaderCommandRegistrar 類

PlugInLoaderCommandRegistrar 類完成 UI 命令的註冊,它繼承自 Microsoft.Practices.EnterpriseLibrary.Configuration.Design 中的 CommandRegistrar 類,需要實現其 Register() 以完成註冊。
在此我們關注一下其中的一個私人方法:AddPlugInLoaderCommand() ,其他方法請參見源碼。AddPlugInLoaderCommand() 方法的代碼如下:

        private void AddPlugInLoaderCommand()
        {
            ConfigurationUICommand cmd =
                ConfigurationUICommand.CreateSingleUICommand(
                this.ServiceProvider,
                "Plug-In Loader Application Block",
                "Add the Plug-In Loader Application Block",
                new AddPlugInLoaderSettingsNodeCommand(this.ServiceProvider),
                typeof(PlugInLoaderSettingsNode));
            this.AddUICommand(cmd, typeof(ConfigurationApplicationNode));
            this.AddDefaultCommands(typeof(PlugInLoaderSettingsNode));
        }

在此方法中,建立了一個 ConfigurationUICommand 類的執行個體,此類是 UI  的命令,它註冊了一個在建立節點時需要執行的命令:AddPlugInLoaderSettingsNodeCommand 類。AddPlugInLoaderSettingsNodeCommand 類繼承自 AddChildNodeCommand 類,並實現了方法 ExecuteCore() ,以完成在建立節點時的其他預設操作。在此實現的 ExecuteCore() 方法為應用程式塊的根節點產生了一個 PlugInProviderCollectionNode 配置節點。

4.2 PlugInLoaderNodeMapRegistrar 類

PlugInLoaderNodeMapRegistrar 類繼承自 NodeMapRegistrar 類,主要重寫了其 Register ,用於註冊二個提供者子類 NaivePlugInProvider 和 InjectionPlugInProvider 類的配置資料類和配置節點的映射, PlugInProviderCollectionNodeBuilder.CreatePlugInProviderNode() 方法中的語句:

PlugInProviderNode pipNode = this.NodeCreationService.CreateNodeByDataType( pipData.GetType(), new object[] { pipData }) as PlugInProviderNode;

中的方法 CreateNodeByDataType() 就是使用節點映射來建立節點的。

4.3 PlugInLoaderCommandRegistrar 類

PlugInLoaderCommandRegistrar 類用於註冊各節點可以建立的子節點的右鍵功能表命令,在此不再詳述。

5 配置控制台的執行註冊

配置控制台的註冊包括二個方面:註冊 UI 、配置的序列化和還原序列化,這是配置控制台和自訂配置的介面,上面所有的類都會通過此介面被配置控制台直接和間接的使用。
在此將這個註冊類命名為 PlugInLoaderConfigurationDesignManager ,PlugInLoaderConfigurationDesignManager 類繼承自 ConfigurationDesignManager 類。在此需要重寫其中的三個方法:Register()、ConfigurationSectionInfo() 和 OpenCore() 。
其中:
  • Register() 方法註冊 UI 命令;
  • ConfigurationSectionInfo() 方法用於將節點序列化為 XML 設定檔;
  • OpenCore() 方法使用者將設定檔還原序列化為 UI 上的配置節點。

配置控制台就是通過上面三個方法來完成配置的開啟、修改和儲存的。

最後,開啟項目的 AssemblyInfo.cs 檔案,在其中加上以下語句:

[assembly: ConfigurationDesignManager(typeof(PlugInLoaderConfigurationDesignManager))]

它告訴配置控制台:“我是一個用於可視化配置的程式集,載入我吧!!!”,如果沒有這行語句,配置控制台將會對此程式集視而不見。

6 小結

在完成上面各步驟後,我們的應用程式塊就可以使用 Enterprise Library 配置控制台來進行可視化配置了。
討論和代碼下載請到:http://forum.entlib.net.cn/yaf_postst38_Enterprise-Library-.aspx。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.