gpt4 book ai didi

delphi - 如何将代码动态注入(inject)到 Delphi 中的事件处理程序中?

转载 作者:行者123 更新时间:2023-12-03 14:50:45 25 4
gpt4 key购买 nike

为了调试/性能测试,我想在运行时动态地将日志记录代码添加到给定类型组件的所有事件处理程序中。

例如,对于数据模块中的所有数据集,我需要在 BeforeOpenAfterOpen 事件中运行代码来捕获开始时间,并记录耗时在 AfterOpen 中。

我更愿意动态地执行此操作(无组件子类化),这样我就可以仅在需要时以最小的努力将其添加到所有现有的数据模块和表单中。

迭代所有组件并按其类型进行过滤很容易,但对于已分配事件处理程序的组件,我需要一种方法来存储现有事件处理程序,并分配新的修改后的事件处理程序它首先进行日志记录,然后调用已经存在的原始代码。

所以这段代码

procedure TMyDatamodule.OnBeforeOpen(Sender: TDataset);
begin
SomeProc;
end;

在运行时会变成

procedure TMyDatamodule.OnBeforeOpen(Sender: TDataset);
begin
StoreStartTime(Sender); // injected code

SomeProc;
end;

是否有可以应用的设计模式,或者甚至是一些示例代码来展示如何在 Delphi 中实现这一点?

最佳答案

您可以使用以下方案重新连接数据集:

type
TDataSetEventWrapper = class
private
FDataSet: TDataSet;
FOrgAfterOpen: TDataSetNotifyEvent;
FOrgBeforeOpen: TDataSetNotifyEvent;
procedure MyAfterOpen(DataSet: TDataSet);
procedure MyBeforeOpen(DataSet: TDataSet);
protected
property DataSet: TDataSet read FDataSet;
public
constructor Create(ADataSet: TDataSet);
destructor Destroy; override;
end;

constructor TDataSetEventWrapper.Create(ADataSet: TDataSet);
begin
Assert(ADataSet <> nil);
inherited Create;
FDataSet := ADataSet;
FOrgAfterOpen := FDataSet.AfterOpen;
FOrgBeforeOpen := FDataSet.BeforeOpen;
FDataSet.AfterOpen := MyAfterOpen;
FDataSet.BeforeOpen := MyBeforeOpen;
end;

destructor TDataSetEventWrapper.Destroy;
begin
FDataSet.AfterOpen := FOrgAfterOpen;
FDataSet.BeforeOpen := FOrgBeforeOpen;
inherited;
end;

procedure TDataSetEventWrapper.MyBeforeOpen(DataSet: TDataSet);
begin
if Assigned(FOrgBeforeOpen) then
FOrgBeforeOpen(DataSet);
end;

procedure TDataSetEventWrapper.MyAfterOpen(DataSet: TDataSet);
begin
if Assigned(FOrgAfterOpen) then
FOrgAfterOpen(DataSet);
end;

MyAfterOpenMyBeforeOpen 中,您可以在调用原始事件处理程序之前、之后或前后引入代码。

使用 OwnsObjects := true 将包装器对象收集到 TObjectList 中,当您清除或释放对象列表时,所有内容都将恢复为原始状态。

警告:要使此代码正常工作,必须在创建包装器时连接事件,并且禁止手动重新分配这些事件。

关于delphi - 如何将代码动态注入(inject)到 Delphi 中的事件处理程序中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2441672/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com