转载

ERPSYSTEM开发教程04 框架模块管理

从DEMO程序获知,

框架主程序工程文件里Forms替换为uTangramFramework,

每个模块都有一个TModule子类和一个GetModuleClass导出函数

那么框架是如何进行模块管理的呢?

我们先从模块入手

unit DllOnePlugin; interface uses SysUtils,Classes,uTangramModule,SysModule,RegIntf; Type   TUserModule=Class(TModule)   private    public   Constructor Create; override;  Destructor Destroy; override;  procedure Init; override;  procedure final; override;  procedure Notify(Flags: Integer; Intf: IInterface); override;  class procedure RegisterModule(Reg:IRegistry);override;  class procedure UnRegisterModule(Reg:IRegistry);override;   End; implementation initialization   RegisterModuleClass(TUserModule); finalization end. 

这是模块的TModule子类, initialization下方的代码是被最先执行的 ,我们看一下 RegisterModuleClass函数放在uTangramModule.pas

unit uTangramModule; {$weakpackageunit on} interface  uses SysUtils,RegIntf,SysModule;  procedure InstallModule(Reg:IRegistry); procedure UnInstallModule(Reg:IRegistry); function GetModuleClass:TModuleClass;  Exports   InstallModule,   UnInstallModule,   GetModuleClass;  implementation  var FModuleClass:TModuleClass;  procedure RegisterModuleClass(ModuleClass:TModuleClass); begin   FModuleClass:=ModuleClass; end;  function GetModuleClass:TModuleClass; begin   Result:=FModuleClass; end;  end.

RegisterModuleClass(TUserModule);其实就是将模块里的TModule子类保存到一个类引用变量 FModuleClass

而导出函数GetModuleClass则返回的 FModuleClass ,因此通过导出函数GetModuleClass就可以获得模块的TModule子类

接下来我们看主程序

Forms替换为uTangramFramework,而uTangramFramework文件里定义了一个Application对象,也就是说

Program HOST;  uses   uTangramFramework,   MainForm in 'MainForm.pas' {FrmMain};  {$R *.res}  begin   Application.Initialize;   Application.MainFormOnTaskbar := True;   Application.CreateForm(TFrmMain, FrmMain);   Application.Run; end.

这里的Application对象其实由uTangramFramework里定义的

unit uTangramFramework  TTangramApp=Class  var   Application:TTangramApp;  initialization   Application:=TTangramApp.Create; finalization   Application.Free;

这样,程序启动之初就会创建由框架定义的 Application 对象,接下来我们就从这行代码开始,进行调试,看模块是如何被管理的

ERPSYSTEM开发教程04  框架模块管理

首先进入TangramApp构造函数

ERPSYSTEM开发教程04  框架模块管理

这里的 FLoadModuleFromRegistry 是TTangramApp的 LoadModuleFromRegistry 属性变量,设置框架默认是从XML进行模块加载

而FModuleMgr是一个TModuleMgr对象,负责模块的管理,进行模块管理类的构造函数

ERPSYSTEM开发教程04  框架模块管理

这里创建了一个TObjectList 对象,该对象用于保存模块列表。

TSingletonFactory.Create(IRegistry,@CreateRegObj);几行是类厂的创建,这部分在接口管理里详细介绍。

继续执行,当所有包含 initialization部分的单元执行过后,就到了程序入口

ERPSYSTEM开发教程04  框架模块管理

ERPSYSTEM开发教程04  框架模块管理

可以看出,其实TTangramApp只是起了几个同名函数,实际调用还是交给了Forms的Application对象,使得主程序在启动之前有机会进行一些初始化工作

接下来运行到Run函数

ERPSYSTEM开发教程04  框架模块管理

FLoadModuleFromRegistry 在构造函数里已经设置为True,而我们没有修改这个属性,所以在这里开始进行模块的自动加载

这里调用模块管理类TModuleMgr对象FModuMgr进行模块加载,进入LoadModules

ERPSYSTEM开发教程04  框架模块管理

GetModuleList函数负责从XML文件读取需要自动加载的模块文件路径,保存到aList

ERPSYSTEM开发教程04  框架模块管理

这里先是判断文件是否存在,如果存在则准备加载

ERPSYSTEM开发教程04  框架模块管理

这里根据模块的文件创建一个TTangramModule对象,用于负责模块的加载

ERPSYSTEM开发教程04  框架模块管理

ERPSYSTEM开发教程04  框架模块管理

这里判断模块的类型然后进行加载,加载完成后

@GetModuleClassPro := GetProcAddress(FModuleHandle, 'GetModuleClass');   if Assigned(GetModuleClassPro) then   begin     FModuleCls:=GetModuleClassPro;     FValidModule:=FModuleCls<>nil;     if (FModuleCls<>nil) and (CreateModuleObjInstance) then       FModuleObj:=FModuleCls.Create;   end;

获得模块的导出函数GetModuleClass,如果存在这个函数则保存并调用,将返回值保存到FModuleCls,这个FModuleCls保存的就是模块里的TModule子类,并创建对象

procedure TModuleMgr.LoadModuleFromFile(const ModuleFile: string); var Module:TTangramModule; begin   try     Module:=TTangramModule.Create(ModuleFile,self.FLoadBatch);     if Module.IsValidModule then       FModuleList.Add(Module)     else Module.Free;   Except     on E: Exception do     begin       WriteErrFmt(Err_LoadModule, [ExtractFileName(ModuleFile), E.Message]);     end;   end; end;

如果是一个有效模块,则添加到对象列表FModuleList

procedure TTangramApp.Run; begin   if FLoadModuleFromRegistry then   begin     FModuleMgr.LoadModules;     FModuleMgr.Init;   end;   Forms.Application.Run;   FModuleMgr.final; end;

当所有模块加载完成后,开始进行模块初始化

ERPSYSTEM开发教程04  框架模块管理

这里取出模块对象列表FModuleList里的每一个对象进行初始化

ERPSYSTEM开发教程04  框架模块管理

注意这里的 FModuleObj.Init FModuleObj是一个TModule对象,是在模块加载时调用GetModuleClass返回模块里的TModule子类创建的对象,

而Init在TModule里是虚函数,所以这里实际调用的实际是模块里的TModule子类实现的Init函数

ERPSYSTEM开发教程04  框架模块管理

当所有模块都初始化过后就进入消息循环,直到主窗体退出则调用模块的终止化函数

procedure TTangramApp.Run; begin   if FLoadModuleFromRegistry then   begin     FModuleMgr.LoadModules;     FModuleMgr.Init;   end;   Forms.Application.Run;   FModuleMgr.final; end;

TModuleMgr提供了两个接口IModuleLoader,IModuleInstall,提供给开发者进行自定义模块加载安装

视频教程地址:

ERPSYSTEM开发教程01     http://pan.baidu.com/s/1kT7Rb3D

ERPSYSTEM开发教程02     http://pan.baidu.com/s/11xN5s

框架源代码下载地址            http://pan.baidu.com/s/1jGIc2Su

DEMO源代码下载地址         http://pan.baidu.com/s/1bnyEafH

联系QQ:1330009208 (验证信息请填ERPSYSTEM)

正文到此结束
Loading...