【问题标题】:How can I get the reference to TDSServerClass in TDSServerClass.OnCreateInstance event handler?如何在 TDSServerClass.OnCreateInstance 事件处理程序中获取对 TDSServerClass 的引用?
【发布时间】:2016-08-08 14:13:30
【问题描述】:

我正在使用 Datasnap 构建一个中间件,它是独立于业务逻辑的。为了广泛支持不同的客户端应用程序,我将业务逻辑封装到 TDataModule 的多个子类中,并将它们作为 REST api 公开给客户端。因此子类的数量和类的类型是动态变化的,并作为插件加载。

根据 Delphi XE 的设计模式,我需要创建一个 TDSServer 实例作为“服务器”,以及多个 TDSServerClass 实例,它们像适配器一样工作,每个都为我的 TDataModule 子类之一提供服务。

类链是: 一个 TDSServer -> 多个 TDSServerClass(es) -> 我的 TDataModule 子类

我的问题是在 TDSServerClass.OnCreateInstance 事件处理程序中找到 TDSServerClass 实例和我的 TDataModule 子类的对应关系。

设置这个链并保持对应关系,如果我有 10 个子类,例如:

  1. 我创建了 1(one) 个 TDSServer 实例,然后创建了 10 个 TDSServerClass 实例,每个实例服务一个 TDataModule 子类(我已将子类的 ID 存储在 TDSServerClass.Tag 属性中。李>
  2. 我在中间件启动时为每个子类创建了 10 个池,每个池中有 10 个子类的实例(所有池中总共有 100 个实例)。
  3. 我将 TDSServerClass 实例的“OnGetClass”、“OnCreateInstance”、“OnDestroyInstance”事件处理程序设置为我的程序来控制我的 TDataModule 子类的创建。
  4. 在 OnCreateInstance 事件处理程序中(当 REST api 被 客户端),我想从对面的子类实例中提取一个实例 游泳池。

我的问题是我无法保留 TDSServerClass->我的子类对应关系。

中间件启动时,TDSServerClass实例的创建如下:

FServerClasses[Len].OnGetClass := DSServerClassGetClass;
FServerClasses[Len].Tag := Len;
FServerClasses[Len].OnCreateInstance := DSServerClass1CreateInstance;
FServerClasses[Len].OnDestroyInstance := DSServerClass1DestroyInstance;

Datasnap服务器启动时,触发了OnGetClass事件,效果很好,我可以通过如下事件处理参数找到对应关系:

procedure TMainServerContainer.DSServerClassGetClass(
  DSServerClass: TDSServerClass; var PersistentClass: TPersistentClass);
begin
  PersistentClass := FindClass(FServerPersistentClasses[DSServerClass.Tag]);
end;

当客户端应用调用 REST api 时,TDSServerClass 触发 OnCreateInstance 事件,让我从池中获取子类实例。但是在 OnCreateInstance 和 OnDestroyInstance 事件处理程序中,我无法让它工作。

例如 OnCreateInstance 的事件处理器原型是这样的:

DSServerClassCreateInstance(
DSCreateInstanceEventObject: TDSCreateInstanceEventObject);

我对 TDSCreateInstanceEventObject 进行了一些研究,但没有找到对触发事件的 TDSServerClass 的任何引用。

请帮助我。非常感谢!

【问题讨论】:

  • 不。相反,轮到我创建子类的实例并分配给 ServerClassInstance 属性,以覆盖 Datasnap 处理的默认创建。

标签: delphi dynamic rtti datasnap


【解决方案1】:

编辑

好的,让我们看看我现在是否明白了。您有 10 个 TDSServerClass 实例,对吗?您需要找出这 10 个函数中的哪一个调用了该函数。

我会采用的答案是有 10 个不同的 DSServerClassxCreateInstance 实现和 10 个不同的 DSServerClassxDestroyInstance 实现,每个 TDataModule 一个,有点像这样:

FServerClasses[3].OnCreateInstance := DSServerClass3CreateInstance;

它可能看起来有点麻烦,根据你的实现,你也许可以使用泛型来整理东西,但它简单而有效。

如果您真正想要的只是 TDataModule 条目,这里有一个关于如何使用泛型的想法:

.....

function DSServerClassCreateInstance< T : TDataModule > : TDServerInstance;

....

FServerClasses[3].OnCreateInstance := DSServerClassCreateInstance< MyDataModule3 >;

【讨论】:

  • 谢谢你,Dsm。我没说清楚,是我的问题。我已经修改了问题。再次感谢您!
  • 我已经相应地修改了我的答案
  • 非常感谢,根据您的想法我已经解决了我的问题,我创建了一个 TDSServerClass 的子类,并将 TDataModule 类的类名保存在其中。谢谢你的建议,很有帮助。
猜你喜欢
  • 2013-05-06
  • 1970-01-01
  • 1970-01-01
  • 2012-05-26
  • 1970-01-01
  • 2010-09-09
  • 2011-12-12
  • 1970-01-01
  • 2011-05-26
相关资源
最近更新 更多