Prism學習(3)---實現可插拔的模塊


上一章中,我使用Unity重構了解決方案。不過在Application工程中仍然需要引用其他各個依懶項。很明顯,這樣做並不能實現計算器模塊的可插拔。今天,將以此為目標,對該解決方案進行再次的重構。 

首先,在使用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框架,共同進步。請大家多多指教。

 

在此,奉上該解決方案的源碼:請點擊  這里 下載。



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM