65.9K
CodeProject 正在变化。 阅读更多。
Home

配置 DLL 以便动态加载和运行

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.50/5 (5投票s)

2006年2月28日

CPOL

3分钟阅读

viewsIcon

37713

downloadIcon

529

动态加载DLL,配置它们,并在单元测试和生产环境中使用不同的DLL/存根。

引言

本文可能在单元测试应用程序层时有用。在单元测试时,输出应该已知才能进行测试。这可以通过存根来实现。在存根中,您可以创建所需的输出以使测试通过。尽管如此,存根当然不应该在生产环境中被调用。那么,如何在单元测试时“开启”存根,而在生产环境中“关闭”它呢?本文介绍了一种通过在配置文件中配置来动态加载程序集的方法。

要使用演示,请确保已安装NUnit

使用代码

主要使用的类是ServiceProviderFactory。此工厂在其Create方法中激活DLL。在此之前,它必须通过调用Configure方法进行配置。这通常在构造函数中完成。以下代码演示了这一点

ServiceProviderFactory.Configure(
ResourceHelper.GetResourceFile(typeof(WalletUt).Assembly, 
                               "configFile.xml"));

请注意,它使用了resourceHelper。此助手加载嵌入在程序集中的资源。在上面的代码行中,助手从WalletUt-assembly加载config.xml文件。

可以使用config.xml文件中给定的名称或其类型在Create方法上创建程序集。以下显示了这一点

IProcesLayer _wallet = (IProcesLayer) 
 ServiceProviderFactory.Create("Wallet");
IProcesLayer _wallet = (IProcesLayer) 
 ServiceProviderFactory.Create(typeof(IProcesLayer));

内部工作原理

要为config.xml文件使用特定的格式,我们可以针对模式进行验证。要创建模式,我首先创建了XML文件,然后使用XSD工具(Visual Studio环境的一部分)创建了模式。然后可以将此模式与XmlValidatingReader一起使用来验证config.xml文件。以下屏幕截图简要显示了使用XSD工具创建模式的过程。

create the schema with tool XSD

config.xml文件包含ServiceProviders。ServiceProvider在ServiceProvider类中定义。此类包含要加载的程序集的type(“namespace.class”'assembly-name')。它还有一个可以指定的InterfaceType。这有助于指定一个接口,并且此接口可以位于与演示中不同的程序集中。这样,接口就可以与其他项目共享,因此不必引用程序集本身。

ServiceProvider包含一个InitializeData参数,该参数可用于传递一些初始化数据。通过这种方式,可以从不同的(测试)项目中使用的存根,每个项目由于InitializeData不同而期望不同的结果。非常强大!现在,存根不必用不同的ifs编程来过滤不同的程序流程。

最后一个参数ServiceProvider是ServiceProvider的名称。这不仅仅是为了使每个ServiceProvider唯一。它还可以用于创建程序集。创建程序集可以基于其接口或您在配置文件中给它的名称。这样做是因为可能存在具有相同接口的更多类。因此,通过给它们一个不同的名称,您也可以加载它们。

演示应用程序为其proceslayertest应用程序具有以下config.xml文件

<?xml version="1.0" encoding="utf-8" ?> <serviceproviders 
         xmlns= "urn://YourCompany.org/XMLSchema1.xsd">
   <serviceproviders>
   
      <serviceprovider interfacetype="Interfaces.IProcesLayer, Interfaces"
         type="ProcesLayer.Wallet, ProcesLayer">
         <name>Wallet</name>
      </serviceprovider>

      <serviceprovider initializedata="150" 
           interfacetype="Interfaces.IServiceLayer, Interfaces"
           type="ServiceLayer.ServiceStub, ServiceLayer.Stub">
         <name>ServiceStubLayer</name>
      </serviceprovider>

   </serviceproviders>
</serviceproviders>

以下config.xml文件是用于“production”应用程序,即Windows应用程序

<?xml version="1.0" encoding="utf-8" ?>
   <serviceproviders 
     xmlns= "urn://YourCompany.org/XMLSchema1.xsd">
   <serviceproviders>
   
      <serviceprovider interfacetype="Interfaces.IProcesLayer, Interfaces"
         type="ProcesLayer.Wallet, ProcesLayer">
         <name>Wallet</name>
      </serviceprovider>

      <serviceprovider interfacetype="Interfaces.IServiceLayer, Interfaces"
         type="ServiceLayer.Service, ServiceLayer">
         <name>ServiceLayer</name>
      </serviceprovider>

   </serviceproviders>
</serviceproviders>

从这两个示例中应该可以清楚地看到,只有服务层被切换了。相同的进程层既从“production”应用程序调用,也从ProceslayerTest应用程序调用。

ServiceProvider的数组嵌入在ServiceProviders中。请注意内部命名空间(= urn://YourCompany.org/XMLSchema1.xsd)与配置文件中的命名空间相同。此命名空间应仔细选择。最好选择您的公司名称。

在测试环境中,serviceLayer-serviceprovider的类型为“ServiceLayer.ServiceStub, ServiceLayer.Stub”。而在“production”环境中,此提供商的类型为“ServiceLayer.Service, ServiceLayer”。这就是我所说的切换。这可以重定向到另一个层。

关注点

使用NMock对象可能是测试应用程序中的层的另一种方法。

在生产环境中,使用initialize数据参数很有意义。通过设置参数,您可以例如打开或关闭跟踪。

历史

  • 版本1.0,2006年2月14日。
© . All rights reserved.