插件框架Extensible Framework for Delphi

工作需要开发的一套插件框架,给应用程序提供灵活的插件支持,基于Dll / Interface实现。

 

先上个图 

 

这是个标准的基于插件的应用,下拉框里的就是由5个插件Dll提供的功能。主程序中定义了一个接口,而插件Dll则提供这个接口的实现。

使用也很简单,在窗口上放置一个TExtensionManager组件,设置一下插件的读取路径就可以了。

 

框架中有3个重要概念,ServiceHost,Module(模块)和扩展(Extension)

1.ServiceHost是整个框架的灵魂,不管是主程序中还是插件中,都通过他来查询和使用其他的插件对象。

下面是一段使用示例代码:

(ServiceHost as ILoggingService).Log("This is a log");

(ServiceHost as IParameterService).SetValue("Param1", "Value1");

(ServiceHost as IMyPlugin).Foo();

(ServiceHost as IMyExtension).Execute();

 

2.Module是Extension的容器,即一个Module包含多个Extension。但实际上Module本身并不提供任何功能,也不提供Extension的管理功能,仅仅为Extension提供逻辑上的分组,同时为应用程序提供分组相关的信息。一个插件Dll中可以包含多个Module。

 

3.Extension是扩展对象管理类,当某个类实现了插件接口后,通过此对象对外发布,并由此对象管理其生命周期。

 

 

另外,框架里还提供了一些常用的服务,也是做为插件存在的,如上面的ILoggingService和IParameterService

IParameterService
  参数服务,为应用程序和扩展提供参数支持,如 $(AppPath)

IRegistryService
  注册表服务,用于信息储存和读取

ILoggingService
  日志服务,通过信道将消息输出到不同的位置

IChannel
  日志信道,用于将消息输出到指定的位置

ILocalizationService
  本地化服务,用于提供本地化的资源

ILocaleSource
  本地化服务数据源

ISplashService
  闪屏服务,用于访问闪屏窗口

IDialogService
  对话框服务,用于提供各种对话框

ILoginService
  登录服务,用于控制用户登录

 

再贴几张Demo的图吧

 

示例代码:

 

View Code
// 主程序
unit uModule;

interface

implementation

uses
  EFToolServices, EFModule, EFWinRegistry, EFLogging, EFParameter;

initialization
  TInterfaceExtension.Create(IRegistryService, TWindowsRegistryService.Create,
    '2011.08.11''RegistryService''IRegistryService Provider''Author: sephil');
  TInterfaceExtension.Create(ILoggingService, TLoggingService.Create,
    '2011.08.11''LoggingService''ILoggingService Provider''Author: sephil');
  TInterfaceExtension.Create(IParameterService, TParameterService.Create,
    '2011.08.11''ParameterService''IParameterService Provider''Author: sephil');
end.

 

 

View Code
// 插件
unit uDllImpl;

interface

implementation

{$I EFDef.inc}

uses
  EFExports, { export dll entry proc }
  EFSystem, EFToolServices, EFModule, EFSysUtils,
  uDocIntf, Windows, Messages, SysUtils;

type
  TDllObject = class(TInterfacedObject, IDllObject)
  private
    procedure ExecOpen;
    procedure ExecInsert(CanUndo: Boolean);
  end;

  TDllModule = class(TModule)
  protected
    class function InitializeComponents(Host: IInterface): Integer; override;

    procedure UpdateDesctiption; override;
  public
    procedure Initialize; override;
    procedure Finalize; override;
  end;

{ TDllObject }

procedure TDllObject.ExecOpen;
var
  S: WideString;
begin
  (ServiceHost as IParameterService).GetValue('$(APPPATH)', S);
  S := S + '\TextDoc.txt';

  (ServiceHost as IDocument).Open(S);
end;

procedure TDllObject.ExecInsert(CanUndo: Boolean);
var
  S: string;
begin
  S := FormatDateTime('c', Now);

  SendMessage((ServiceHost as IDocument).GetHWND,
    EM_REPLACESEL, WPARAM(CanUndo), LPARAM(PChar(S)));
end;

{ TDllModule }

function GetModule: string;
begin
  SetString(Result, nil, MAX_PATH);
  SetLength(Result, GetModuleFileName(HInstance, @Result[1], MAX_PATH));
end;

class function TDllModule.InitializeComponents(Host: IInterface): Integer;
var
  S: WideString;
begin
  (ServiceHost as ILoggingService).Write('TDllModule.InitializeComponents');
  (ServiceHost as IParameterService).GetValue('$(D2007)', S);
  if {$IFDEF DELPHI12_UP}not{$ENDIF} StrToBool(S) then Result := 0 else Result := 1;
  if Result <> 0 then
    (ServiceHost as ILoggingService).Write(ExtractFileName(GetModule) + ' skipped')
  else
    (ServiceHost as ILoggingService).Write(ExtractFileName(GetModule) + ' loaded');
end;

procedure TDllModule.UpdateDesctiption;
begin
  // original info from version info
  inherited;
end;

procedure TDllModule.Initialize;
var
  Intf: ILoggingService;
begin
  inherited;
  (ServiceHost as ILoggingService).Write('TDllModule.Initialize');
end;

procedure TDllModule.Finalize;
begin
  inherited;
  (ServiceHost as ILoggingService).Write('TDllModule.Finalize');
end;

initialization
  RegisterModuleClass(TDllModule);
  TExtensionFactory.Create(IDllObject, TDllObject, '2011.08.08',
    'Dll Object''IDllObject implementation''Author: sephil');
end.

 

posted @ 2012-02-22 23:52  Sephil  阅读(4016)  评论(7编辑  收藏  举报