zoukankan      html  css  js  c++  java
  • Prism学习--实现可插拔的模块

    首先,在使用Prism框架加载的程序集中分别添加一个类,并让这些类实现IModule接口。当Prism框架加载某个程序集后,将首先在程序集中搜索实现了该接口的类。之后将会调用该接口的Initialize方法。于是,我们可以在这个方法中实现程序集内部的初化始操作,或者执行某个动作。通过这种机制,可以实现程序集的完全解藕。具体的操作如下:

    1. 在CalculatorLibrary 程序集中添加一个类:CalculatorModule,并让其实现IModule接口。代码如下:

    复制代码
     2     public class CalculatorModule:IModule
     3     {
     4         public CalculatorModule(IUnityContainer container)
     5         {
     6             this.container = container;
     7         }
     8         void IModule.Initialize()
     9         {
    10             container.RegisterType<ICalculator, Calculator>();
    11             container.RegisterType<ICalculatorReplLoop, CalculatorReplLoop>();
    12         }
    13 
    14         IUnityContainer container;
    15     }
    复制代码

    2. 在InputOutputLibrary 程序集中添加一个类:InputOutputModule,并让其实现IModule接口。代码如下:

    复制代码
     2     public class InputOutputModule:IModule
     3     {
     4         public InputOutputModule(IUnityContainer container)
     5         {
     6             this.container = container;
     7         }
     8         void IModule.Initialize()
     9         {
    10             container.RegisterType<IInputService, ConsoleInputService>();
    11             container.RegisterType<IOutputService, ConsoleOutputService>("OutputService1");
    12             container.RegisterType<IOutputService, MsgBoxOutputService>("OutputService2");
    13         }
    14 
    15         IUnityContainer container;
    16     }
    复制代码

    3. 在CommandParserLibrary 程序集中添加一个类:InputOutputModule,并让其实现IModule接口。代码如下:

    复制代码
     2     public class InputParsingModule : IModule
     3     {
     4         public InputParsingModule(IUnityContainer container)
     5         {
     6             this.container = container;
     7         }
     8         void IModule.Initialize()
     9         {
    10             container.RegisterType<IInputParserService, InputParserService>();
    11         }
    12 
    13         IUnityContainer container;
    14     }
    复制代码

    4. 在解决方案中新建一个类库:MainModuleLibrary,在其中添加一个类:MainModule,并实现IModule接口。这个类库将会作为计算器模块的入口,在该类的Initialize方法中将会启动计算器。代码如下:

    复制代码
     2     public class MainModule: IModule
     3     {
     4         public MainModule(IServiceLocator serviceLocator)
     5         {
     6             this.serviceLocator = serviceLocator;
     7         }
     8         void IModule.Initialize()
     9         {
    10             ICalculatorReplLoop loop = 
    11                 serviceLocator.GetInstance<ICalculatorReplLoop>();
    12 
    13             loop.Run();
    14         }
    15 
    16         IServiceLocator serviceLocator;
    17     }
    复制代码

    到此,程序集部分的代码全部完成。可以看到,前三个程序集中Module类,使用Initialize方法将各个类注册到了Container对象中,由Prism框架进行管理。我们可以在需要的时候,在任何地方通过Prism框架将其取得调用;第四个程序集作为计算器的入口,在Module类的Initialize方法中启动计算器。这里的代码在上一章中基本都用过,在此不再描述。 

    经过上面的修改,我们可以非常方便的对其进行调用,并且不需要任何的引用,实现了完全的解藕。下面的代码,将指示我们如何在主程序中启动这些程序集。如下:

    复制代码
     2     static void Main(string[] args)
     3     {
     4         UnityContainer Container = new UnityContainer();
     5 
     6         Container.RegisterInstance<IServiceLocator>(
     7             new UnityServiceLocatorAdapter(Container));
     8 
     9         Container.RegisterType<IModuleInitializer, ModuleInitializer>();
    10 
    11         ILoggerFacade logger = new TextLogger();
    12         Container.RegisterInstance<ILoggerFacade>(logger);
    13 
    14         Container.RegisterType<IModuleCatalog, ConfigurationModuleCatalog>();
    15 
    16         Container.RegisterType<IModuleManager, ModuleManager>();
    17 
    18         IModuleManager Manager = Container.Resolve<IModuleManager>();
    19         Manager.Run();
    20     }
    复制代码

     上面的代码中,ModuleInitializer  TextLogger, ModuleCatalog 三个类,都是ModuleManager的构造函数中所需要的。如果不注册,程序将会出错。在当前框架中,实现了ILoggerFacade接口的类有多个。直接使用RegisterType来注册,也将会报错,我没有看源代码,不知道他的名称是什么,所以在此直接使用实体注册,这也可以实现同样的效果。

    在程序启动运行时,Prism框架会去系统的配置文件中加获取模块的信息,并加它们加载到系统中。这些配置跟上一章中的类的配置不一样,具体请参考下面的xml文件:

    复制代码
     2 <?xml version="1.0" encoding="utf-8" ?>
     3 <configuration>
     4   <configSections>
     5     <section name="modules"
     6              type="Microsoft.Practices.Prism.Modularity.ModulesConfigurationSection, Microsoft.Practices.Prism" />
     7   </configSections>
     8   <modules>
     9     <module assemblyFile="CommandParserLibrary.dll"
    10             moduleType="CommandParserLibrary.InputParsingModule, CommandParserLibrary"
    11             moduleName="Parsing"/>
    12     <module assemblyFile="CalculatorLibrary.dll"
    13             moduleType="CalculatorLibrary.CalculatorModule, CalculatorLibrary"
    14             moduleName="Calculator"/>
    15     <module assemblyFile="InputOutputLibrary.dll"
    16             moduleType="InputOutputLibrary.InputOutputModule, InputOutputLibrary"
    17             moduleName="InputOutput"/>
    18     <module assemblyFile="MainModuleLibrary.dll"
    19             moduleType="MainModuleLibrary.MainModule, MainModuleLibrary"
    20             moduleName="Main">
    21       <dependencies>
    22         <dependency moduleName="Parsing" />
    23         <dependency moduleName="Calculator"/>
    24         <dependency moduleName="InputOutput"/>
    25       </dependencies>
    26     </module>
    27   </modules>
    28 </configuration>
    复制代码

    到此,计算器模块的完全解藕顺利完成。我们可以删掉Application中对计算器模块的所有引用。将其它模块编译好后,拷到Application项目的Debug目录下试一下。这个项目,只是Prism框架的一个简单应用。在后续的章节中,我将继续深入研究对该框架的使用。欢迎大家一起来学习Prism框架,共同进步。请大家多多指教。

    在此,奉上该解决方案的源码:请点击 这里 下载。

    http://www.cnblogs.com/prolove2/archive/2012/03/28/2422401.html

     

  • 相关阅读:
    数组作为函数参数传递时
    Tree 笨方法实现
    双向链表
    带头节点的循环链表及两个循环链表的合并
    josephus问题->不带头节点的循环链表
    数组形式链表
    检测qq是否在线
    Python-requests模块
    Python面向对象练习——基于面向对象设计一个对战游戏
    Python-面向对象
  • 原文地址:https://www.cnblogs.com/tianciliangen/p/4968333.html
Copyright © 2011-2022 走看看