【问题标题】:How to make a Web Module know the owner from where it was called?如何让 Web 模块知道它的所有者是从哪里调用的?
【发布时间】:2013-02-27 00:13:16
【问题描述】:

我正在使用 HTTP 服务器,我正在使用 Indy 的 TIdHTTPWebBrokerBridgeTWebModule。我将所有服务器功能封装到一个组件中,这包括 Indy 服务器组件及其相应的 Web 模块。但是,我在弄清楚如何让 Web 模块知道调用它的组件时遇到了一些问题。

假设我有这个组件:

type
  TMyComponent = class(TComponent)
  private
    FServer: TIdHTTPWebBrokerBridge;
  end;

implementation

uses
  MyWebModule;

我知道我必须通过设置请求处理程序来初始化它,我已经通过在这个单元中添加一个initialization 部分来处理它:

initialization
  if WebRequestHandler <> nil then
    WebRequestHandler.WebModuleClass:= WebModuleClass;

然后我将 Web Module 类放在一个单独的单元中:

uses
  MyWebServer;

type
  TMyWebModule = class(TWebModule)
  private
    FOwner: TMyComponent;
  end;

注意我在这个网络模块FOwner: TMyComponent 中的私有字段。这是我无法确定去哪里的地方。如何将其分配给适当的所有者? Web Module 是由 Indy HTTP Server 自动创建和管理的,据我所知,我没有任何控制来设置这样的东西。

我需要访问其所有者的原因是因为我在那里设置了 Web 模块需要能够读取的属性。例如,我的组件上的一个属性是RootDir,它是一个用于读取/写入文件的根目录。我需要能够从 Web 模块中读取此属性。

如何使 Web 模块能够读取其所有者组件的属性?或者一般来说,如何将这个私有字段 FOwner 分配给我的组件实例,从它被实例化的地方?

【问题讨论】:

  • 为什么知道是谁调用它很重要?它用这些信息做什么?我倾向于跟随咒语,调用者可以知道很多关于它调用的内容,但被调用者永远不需要知道谁在调用它。有助于保持事物解耦。
  • 听起来像使用xxm.sf.net就不会遇到的问题
  • @Marjan 我通常会保持东西解耦,但在这种情况下,Web 模块应该如何知道它的设置?既然它都包裹在这个组件中,并且组件的属性是主要存储这些信息的地方,那么 Web 模块怎么会知道这些设置呢?我相信我下面的答案是这种情况下唯一合法的解决方案。在我的例子中,这两个单元是直接相关的,所以它们不需要解耦,它们是相互对应的。
  • 我们拥有的是一个 TWebModule 后代,它只是分派东西,并且该单元将我们的类注册到 WebRequestHandler。然后我们有一个THTTPServer,它聚合(就像你做的那样,但在一个普通的类而不是一个组件中)webbrokerbridge。桥是用nil作为它的所有者创建的,在桥创建后,我们使用桥的祖先TIdHTTPWebBrokerBridgeRegisterWebModuleClass方法在其中注册我们的webmodule后代。像魅力一样工作...... :)

标签: delphi delphi-xe2 indy indy10 httpserver


【解决方案1】:

我在问了这个问题后发现了我的答案

由于不建议创建TIdHTTPWebBrokerBridge 的多个实例,因此您不必担心TMyComponent 的多个不同实例的存在。但是,您确实需要执行自己的检查以确保首先不存在多个实例。但是由于您只有一个该组件的实例,因此您可以放心地在组件的单​​元中声明一个全局变量并将其公开给您的 Web 模块。

不要直接在单元的interface 中声明一个全局变量var。相反,你应该保护它......

function MyComponent: TMyComponent;

implementation

uses
  MyWebModule;

var
  _MyComponent: TMyComponent;

function MyComponent: TMyComponent;
begin
  Result:= _MyComponent;
end;

constructor TMyComponent.Create(AOwner: TComponent);
begin
  inherited;
  _MyComponent:= Self;
end;

destructor TMyComponent.Destroy;
begin
  _MyComponent:= nil;
  inherited;
end;

initialization
  _MyComponent:= nil;
  if WebRequestHandler <> nil then
    WebRequestHandler.WebModuleClass:= WebModuleClass;
end.

【讨论】:

  • 附带说明,也不建议以这种方式将此 Indy 组件包装在组件中,但无论如何我都在这样做。另一种解决方案是根本不公开组件,将其保留为私有,并添加InitMyServerUnInitMyServer 程序。
猜你喜欢
  • 2019-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-28
  • 2014-03-23
  • 1970-01-01
  • 2015-11-10
相关资源
最近更新 更多