⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 un_pluginmanager.~pas

📁 信息系统工作核心代码,若要具体可以联系我,这只是一部分核心代码,大家一起交流分享.谢谢
💻 ~PAS
字号:
unit Un_PluginManager;

interface

uses
  Classes, SysUtils, Forms, Un_Plugin, Un_PluginConfig;

type
  //Id=bpl文件名+插件名
  TPluginList=class
  private
    FStringList: TStringList;
    function GetCount: Integer;
  public
    constructor Create;
    destructor Destroy; override;
    procedure Clear;
    procedure Delete(Index: Integer);
    procedure AddPlugin(Id: string; APlugin: IPlugin);
    function GetPlugin(Index: Integer): IPlugin;
    function GetPluginById(const Id: string): IPlugin;
    function IndexOfName(const Id: string): Integer;
    property Count: Integer read GetCount;
  end;

  TPluginManager=class
  private
    FBplHModules: TStringList;
    FPluginList: TPluginList;
    function GetPlugin(const Id: string): IPlugin;
    function GetCount: integer;
    function GetPluginByIndex(const index: integer): IPlugin;
  private
    procedure Check(Bool: Boolean; ShowInfo: String);
    function ChangeFileExtIsBPL(FileName: string): string;
  protected
    procedure UnloadPlugin(const Id: string); overload; //卸载指定的插件
    procedure UnloadPlugin(const Index: Integer); overload;  //卸载指定的插件
    procedure LoadPlugin(const IniFileName, BplFileName: string);
    procedure UnloadPlugins;
  public
    constructor Create;
    destructor Destroy; override;
    procedure LoadPlugins(Directory: string);
    property Plugin[const id: string]: IPlugin read GetPlugin;
    property PluginByIndex[const index: Integer]: IPlugin read GetPluginByIndex;
    property Count: integer read GetCount;
    property Plugins: TPluginList read FPluginList;
  end;

  TPluginFactory=class
  private
    FPluginManager: TPluginManager;
    function GetPlugins: TPluginList;
  public
    constructor Create;
    destructor Destroy; override;
    class function Instance: TPluginFactory;
    procedure LoadPlugins;
    function GetPlugin(Id: string): IPlugin;
    property Plugins: TPluginList read GetPlugins;
  end;

implementation

{ TPluginList }

procedure TPluginList.AddPlugin(Id: string; APlugin: IPlugin);
begin
  FStringList.AddObject(Id, Pointer(APlugin));
end;

procedure TPluginList.Clear;
begin
  while FStringList.Count>0 do
    Delete(0);
end;

constructor TPluginList.Create;
begin
  FStringList:= TStringList.Create;
end;

procedure TPluginList.Delete(Index: Integer);
var
  Plugin: IPlugin;
begin
  Plugin:= GetPlugin(Index);
  FStringList.Delete(Index);
  Plugin:= nil;
end;

destructor TPluginList.Destroy;
begin
  Clear;
  FStringList.Free;
  inherited;
end;

function TPluginList.GetCount: Integer;
begin
  Result:= FStringList.Count;
end;

function TPluginList.GetPlugin(Index: Integer): IPlugin;
begin
  Result:= IPlugin(Pointer(FStringList.Objects[Index]))
end;

function TPluginList.GetPluginById(const Id: string): IPlugin;
var
  Index: Integer;
begin
  Index:= IndexOfName(Id);
  if Index=-1 then
    raise Exception.Create('未找到插件:'+Id);
  Result:= GetPlugin(Index);
end;

function TPluginList.IndexOfName(const Id: string): Integer;
begin
  Result:= FStringList.IndexOf(Id);
end;

{ TPluginManager }

function TPluginManager.ChangeFileExtIsBPL(FileName: string): string;
begin
  Result:= StringReplace(FileName,'.ini', '.bpl', [rfIgnoreCase]);
end;

procedure TPluginManager.Check(Bool: Boolean; ShowInfo: String);
begin
  if (not Bool) then
    raise Exception.Create(ShowInfo);
end;

constructor TPluginManager.Create;
begin
  FPluginList:= TPluginList.Create;
  FBplHModules:= TStringList.Create;
end;

destructor TPluginManager.Destroy;
begin
  UnloadPlugins;
  FPluginList.Free;
  FBplHModules.Free;
  inherited;
end;

function TPluginManager.GetCount: integer;
begin
  Result:= FPluginList.Count;
end;

function TPluginManager.GetPlugin(const id: string): IPlugin;
var
  Index: Integer;
begin
  Index:= FPluginList.IndexOfName(id);
  Check(index>=0, Format('未找到%s插件.', [id]));
  Result:= GetPluginByIndex(index);
end;

function TPluginManager.GetPluginByIndex( const index: integer ): IPlugin;
begin
  Check(Index<FPluginList.Count, IntToStr(index)+'超出范围 ,没有该索引.');
  Result:= IPlugin(Pointer(FPluginList.GetPlugin(index)));
end;

procedure TPluginManager.LoadPlugin(const IniFileName, BplFileName: string );
var
  i: Integer;
  ImplClass : TPersistentClass;
  obj       : TPersistent;
  Intf      : IPlugin;
  BplHandle : Cardinal;
  PluginConfig: IPluginConfig;
begin
  //载入bpl
  BplHandle:= LoadPackage(BplFileName);
  FBplHModules.Add(intToStr(BplHandle));
  PluginConfig:= TIniPluginConfig.Create(IniFileName);
  try
    for i:= 0 to PluginConfig.GetConfig.Count-1 do begin
      //存入接口变量
      ImplClass:= GetClass(PluginConfig.GetConfig.Strings[i]);
      Check(ImplClass<>nil,
            Format('没有在%s中找到%s类.',
            [BplFileName, PluginConfig.GetConfig.Strings[i]]));
      obj:= ImplClass.Create;
      Check(Supports(obj,
            StringToGUID('{9C03B818-731D-4D8A-AD95-B8D87D07295E}'), Intf),
            ImplClass.ClassName + '不支持插件接口IPlugin.');
      FPluginList.AddPlugin(UpperCase(ExtractFileName(BplFileName)
                            +':'+PluginConfig.GetConfig.Strings[i]), Intf);
    end;
  finally
    PluginConfig:= nil;
  end;
end;

procedure TPluginManager.LoadPlugins(Directory: string);
var
  i: Integer;
  BplFileName: string;
  PluginConfigFile: IPluginConfigFile;
begin
  PluginConfigFile:= TIniPluginConfigFile.Create(Directory);
  try
    for i:= 0 to PluginConfigFile.GetConfigFiles.Count-1 do begin
      BplFileName:= ChangeFileExtIsBPL(PluginConfigFile.GetConfigFiles.Strings[i]);
      if FileExists(BplFileName) then
        LoadPlugin(PluginConfigFile.GetConfigFiles.Strings[i], BplFileName);
    end;
  finally
    PluginConfigFile:= nil;
  end;
end;

procedure TPluginManager.UnloadPlugin(const id: string);
var
  index: Integer;
begin
  index:= FPluginList.IndexOfName(id);
  Check(index>=0, Format('未找到%s插件.', [id]));
  UnloadPlugin(index);
end;

procedure TPluginManager.UnloadPlugin(const index: Integer);
begin
  FPluginList.Delete(index);
end;

procedure TPluginManager.UnloadPlugins;
var
  i: Integer;
begin
  for i:= FPluginList.Count - 1 downto 0 do UnloadPlugin(i);
  for i:= 0 to FBplHModules.Count-1 do begin
    UnloadPackage(StrToInt(FBplHModules.Strings[i]));
  end;
end;

{ TPluginFactory }

constructor TPluginFactory.Create;
begin
  FPluginManager:= TPluginManager.Create;
end;

destructor TPluginFactory.Destroy;
begin
  FPluginManager.Free;
  inherited;
end;

function TPluginFactory.GetPlugin(Id: string): IPlugin;
begin
  Result:= FPluginManager.Plugin[Id];
end;

var
  PluginFactory: TPluginFactory;
function TPluginFactory.GetPlugins: TPluginList;
begin
  Result:= FPluginManager.Plugins;
end;

class function TPluginFactory.Instance: TPluginFactory;
begin
  if PluginFactory=nil then
    PluginFactory:= TPluginFactory.Create;
  Result:= PluginFactory;
end;

procedure TPluginFactory.LoadPlugins;
var
  PluginDir: string;
begin
  PluginDir:= ExtractFilePath(Application.ExeName)+'plugins\';
  FPluginManager.LoadPlugins(PluginDir);
end;

initialization
  PluginFactory:= nil;

finalization
  if PluginFactory<>nil then
    FreeAndNil(PluginFactory);

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -