Как заставить веб-модуль знать владельца, откуда он был вызван?

Я работаю над HTTP-сервером и использую Indy TIdHTTPWebBrokerBridge с TWebModule. Я инкапсулирую все функциональные возможности сервера в один компонент, включая компонент Indy Server и соответствующий ему веб-модуль. Однако у меня возникли некоторые проблемы с выяснением того, как заставить веб-модуль узнать компонент, из которого он был вызван.

Предположим, у меня есть этот компонент:

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

implementation

uses
  MyWebModule;

Я знаю, что должен инициализировать это, настроив обработчик запросов, и я позаботился об этом, добавив в этот блок раздел initialization:

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

Затем у меня есть класс веб-модуля в отдельном модуле:

uses
  MyWebServer;

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

Обратите внимание на приватное поле в этом веб-модуле FOwner: TMyComponent. Вот и затрудняюсь понять, куда идти. Как назначить это соответствующему владельцу? Веб-модуль автоматически создается и управляется HTTP-сервером Indy, поэтому, насколько я знаю, у меня нет никакого контроля, чтобы установить такую ​​​​вещь.

Причина, по которой мне нужен доступ к его владельцу, заключается в том, что у меня там установлены свойства, которые веб-модуль должен иметь возможность читать. Например, у моего компонента есть свойство RootDir, которое является корневым каталогом для чтения/записи файлов. Мне нужно иметь возможность прочитать это свойство из веб-модуля.

Как я могу сделать так, чтобы веб-модуль мог читать свойства своего компонента-владельца? Или вообще, как я могу назначить это приватное поле FOwner экземпляру моего компонента, из которого он был создан?


person Jerry Dodge    schedule 27.02.2013    source источник
comment
Почему важно знать, кто звонил? Что он делает с этой информацией? Я склонен следовать мантре: вызывающий может многое знать о том, что он вызывает, но вызываемый никогда не должен знать ничего о том, кто его вызывает. Помогает держать вещи разделенными.   -  person Marjan Venema    schedule 27.02.2013
comment
Звучит так, как если бы вы использовали xxm.sf.net.   -  person Stijn Sanders    schedule 27.02.2013
comment
@Marjan Я обычно держу вещи разделенными, но в этом случае как еще веб-модуль должен знать свои настройки? Поскольку все это заключено внутри этого компонента, а свойства компонента — это то место, где в основном хранится эта информация, как еще веб-модуль может знать эти настройки? Я считаю, что мой ответ ниже является единственным законным решением для этого сценария. И в моем случае эти две единицы напрямую связаны друг с другом, поэтому их не нужно разделять, они предназначены друг для друга.   -  person Jerry Dodge    schedule 27.02.2013
comment
У нас есть потомок TWebModule, который просто отправляет данные, а модуль регистрирует наш класс с помощью WebRequestHandler. Затем у нас есть THTTPServer, который агрегирует (точно так же, как и вы, но в обычном классе, а не компонент) webbrokerbridge. Бридж создается с владельцем nil и сразу после создания бриджа мы регистрируем в нем наш потомок вебмодуля с помощью метода RegisterWebModuleClass предка бриджа TIdHTTPWebBrokerBridge. Работает как шарм... :)   -  person Marjan Venema    schedule 28.02.2013


Ответы (1)


Я нашел свой ответ через некоторое время после того, как задал этот вопрос

Поскольку не рекомендуется создавать несколько экземпляров TIdHTTPWebBrokerBridge, вам не обязательно беспокоиться о существовании нескольких разных экземпляров TMyComponent. Однако вам необходимо выполнить собственную проверку, чтобы убедиться, что несколько экземпляров не существуют. Но поскольку у вас есть только один экземпляр этого компонента, вы можете чувствовать себя в безопасности, объявляя глобальную переменную в модуле вашего компонента и предоставляя ее вашему веб-модулю.

Не объявляйте глобальную переменную var непосредственно в interface вашего модуля. Вместо этого вы должны защитить это...

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.
person Jerry Dodge    schedule 27.02.2013
comment
Кстати, также не рекомендуется оборачивать этот компонент Indy в компонент таким образом, но я все равно это делаю. Другим решением было бы вообще не открывать компонент, оставить его закрытым и добавить процедуры InitMyServer и UnInitMyServer. - person Jerry Dodge; 27.02.2013