【问题标题】:Can I use class helpers for TWebActionItem or TWebRequest?我可以为 TWebActionItem 或 TWebRequest 使用类助手吗?
【发布时间】:2013-08-14 10:31:34
【问题描述】:

我有大约 20 多个带有相关 OnAction 事件处理程序的 TWebActionItem:

procedure TWebModuleWebServices.WebModuleWebServicesTTLoginAction(Sender: TObject;
  Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);

在 TWebModuleWebServices = class(TWebModule) 上。 (注意:Sender 是一个 TWebActionItem)

这些处理程序都有一些相同的局部变量,“初始化”和“终结”代码。

我已设法将一些代码移至 TWebModuleWebServices 的 AfterDispatch 和 BeforeDispatch 处理程序。

如果我想移动更常见的代码,我需要将数据存储在 BeforeDispatch 的(对象)变量中(并在 OnAction 处理程序和 AfterDispatch 中访问这些变量)。

由于 AfterDispatch 和 BeforeDispatch 具有与 OnAction 处理程序相同的 Sender: TObject; Request: TWebRequest; Response: TWebResponse; 参数,我正在考虑为 TWebActionItem 或 TWebRequest 编写一个类帮助程序。
类助手不允许有数据成员(“E2169 Field definition not allowed after methods or properties”),但是有一个trick with class vars/constructors/destructors
在本文中,作者通过使用 TDictionary 来规避类 var 是全局的这一事实:

TPanelHelper2 = class helper for TPanel
public
  class var
    MetaData: TDictionary<TPanel, string>; //store some strings - an example
  procedure PutData(aData: string);
  function ReadData: string;
  class constructor SetUp;
  class destructor TearDown;
end;

implementation

procedure TPanelHelper2.PutData(aData: string);
begin
  MetaData.AddOrSetValue(Self, aData);
end;

function TPanelHelper2.ReadData: string;
begin
  if MetaData.ContainsKey(Self) then
    Result:=MetaData.Items[Self]
  else
    Result:=''; //or whatever
end;

class constructor TPanelHelper2.SetUp;
begin
  MetaData:=TDictionary<TPanel, string>.Create;
end;

class destructor TPanelHelper2.TearDown;
begin
  MetaData.Free;
end;

要使用它,将 2 个面板放在一个表单上,然后:

Panel1.PutData('panel1string');
Panel2.PutData('panel2string');
ShowMessage('Panel 1 metadata: ' + Panel1.ReadData);
ShowMessage('Panel 2 metadata: ' + Panel2.ReadData);

一个不错的技巧,但它让我想知道我是否可以在我的 TWebModuleWebServices 上做到这一点。我对 Delphi(VMT 等)的内部运作没有足够的了解来回答这些问题:

  1. 这样安全吗?
  2. 是否有更好的方法(类助手有其缺点,请参见 Understanding Delphi Class (and Record) Helpers 中的例如 Class Helpers Go 和 NoGo)?

编辑
上面的问题有一个错误:
由于 AfterDispatch 和 BeforeDispatch 有相同的 Sender: TObject;请求:TWebRequest;响应:TWebResponse;作为 OnAction 处理程序的参数
不正确。
Sender 是 AfterDispath/BeforeDispatch 的 TWebModuleWebservices 和 OnAction 处理程序的 TWebActionItem。我把它留在里面是因为它需要重写一个大问题,而且它对答案不是必需的。

【问题讨论】:

    标签: web-services delphi delphi-xe2


    【解决方案1】:

    这些处理程序都有一些相同的局部变量

    您也可以简单地将这些局部变量转换为 web 模块的私有字段。

    【讨论】:

    • 但是 TWebModule 并不是为每个 WebAction 创建的,是吗?局部变量将被覆盖。这是一个 FWebBrokerBridge := TIdHTTPWebBrokerBridge.Create(Self) 和 FWebBrokerBridge.RegisterWebModuleClass(TWebModuleWebServices);
    • 一个请求总是由网络模块的一个实例处理(通过一个或多个操作)。 (可能有其他实例在不同线程上处理其他请求。)私有字段可以被操作重用——这应该没有问题,因为一次只执行一个操作。我假设无状态服务器 - 请求之间不需要保留状态。
    • 这大大简化了事情!
    【解决方案2】:

    这是安全的,但不一定是解决所提出问题的最佳选择。

    在你的位置,我会去继承。我将从 TWebModule 创建一个子类,并添加所有其他 TWebModule 在该类中具有的所有通用功能。然后我会将其他 TWebModules 的当前祖先更改为这个新的。

    这种方法的好处是您可以缓慢而谨慎地采用它。您可以为您的应用程序创建基本的 TWebModule,为其添加一些行为并选择其他 TWebModule 中的一个来体验继承优势。您可以针对您选择的单个 TWebModule 进行调整、重新设计和测试。

    在那之后,你可以再接再厉,直到全部完成。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-27
      • 2019-11-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多