在企业环境中,允许在内部应用程序中编写并导入插件,而不必改变核心应用的情况十分少见。我认为原因之一在于:以前很难执行这类使用插件的构架。
开发者被迫花大量时间设计构架,或开发替代方案完成其目标。我们都知道,在企业环境中不容易获得大量时间,所以大多数开发者似乎都被迫选择开发替代方案。微软已经用C#和.NET Framework解决这个问题。因此现在开发一款允许动态插入组件,且不必改变核心代码的应用程序已不再重要。
本文中包括的解决方案(参见下载的项目文件)说明如何执行一个简单的插件构架。这个示范解决方案动态执行测试(每个测试为一个插件)并报告结果。每个测试完成不同的任务,并可以添加或删除测试,而不会影响到核心测试引擎的功能。这样我们就可以给应用程序增加测试,而不必重建整个应用程序。我将这个解决方案称为“SystemTests”,它包含四个项目:SharedObjects、TestEngine、TestExamples和TestApplication。
许多允许使用插件的应用程序都有一些激活插件功能的基本层,SystemTests方案也不例外。
共享对象层
共享对象层为主应用程序提供一种与插件通信的方法。主应用程序和插件引用同样的对象。
共享对象(Shared Objects)层由SharedObject项目执行。这个项目包括以下各项:
核心或主应用程序层
主应用程序层是应用程序执行核心功能的地方。这个层把所有插件连接起来,完成所需的报告,并与用户或数据库进行互操作。
主应用程序层由TestEngine项目执行,它包含一个名为“Engine”的类。收集必须运行的测试并运行它们,并通过一个TestEngineState项目将结果返回给调用的应用程序,是Engine类的工作。
LoadConfiguration和CreateTest是Engine类的两个最重要的方法。下面详细说明这两个方法:
通过解析一个XML配置文件确定必须加载哪个插件。LoadConfiguration由列表A中的代码执行,其中的注释对代码进行了解释:
列表A
privatevoid LoadConfiguration(string path)
{
XmlDocument configuration = newXmlDocument();
//Load the given XML file into our XML document.
configuration.Load(path);
//Get a NodeList of the Test nodes.
XmlNodeList tests = configuration.SelectNodes("/TestEngine/Tests/Test");
//Loop through the test nodes and load each test.
foreach (XmlNode test in tests)
{
//Load the enabled attribute to determine if the test is enabled.
XmlAttribute enabled = test.Attributes["Enabled"];
if (enabled.Value.ToLower() == "true")
{
XmlAttribute assemblyPath = test.Attributes["Assembly"];
XmlAttribute typeName = test.Attributes["Type"];
//Call CreateTest to instantiate the test and add it to the
// Tests property.
this.Tests.Add(CreateTest(assemblyPath.Value, typeName.Value));
}
}
}
从指定的装配路径和类型名称中建立一个ITest对象。这个方法如列表B所示,其中的注释说明了从装配中动态初始化一个对象的必要步骤。