如何在 TDSServerClass.OnCreateInstance 事件处理程序中获取对 TDSServerClass 的引用?

How can I get the reference to TDSServerClass in TDSServerClass.OnCreateInstance event handler?

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

根据Delphi XE 的设计模式,我需要创建一个 TDSServer 实例作为 "server",以及多个 TDSServerClass 实例,它们像适配器一样工作,每个服务于我的 TDataModule 子classes.

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

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

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

  1. 我创建了 1(one) 个 TDSServer 实例,然后创建了 10 个 TDSServerClass 实例,每个实例服务于一个 TDataModule subclass(我已经存储了TDSServerClass.Tag 属性 中的子class。
  2. 我在中间件启动时为每个子class创建了10个池,每个池中有10个子class实例(所有池中总共有100个实例)。
  3. 我将 "OnGetClass"、"OnCreateInstance"、"OnDestroyInstance" 的 TDSServerClass 实例的事件处理程序设置到我的过程中,以控制我的 TDataModule 子class.[=49 的创建=]
  4. 在 OnCreateInstance 事件处理程序中(当 REST api 被调用时 client),我想从对面的subclass实例中取出一个实例 池.

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

中间件启动时,创建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 事件让我从池中获取一个子 class 实例。但是在 OnCreateInstance 和 OnDestroyInstance 事件处理程序中,我无法使其工作。

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

DSServerClassCreateInstance(
DSCreateInstanceEventObject: TDSCreateInstanceEventObject);

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

请帮帮我。非常感谢!

编辑

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

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

FServerClasses[3].OnCreateInstance := DSServerClass3CreateInstance;

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

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

.....

function DSServerClassCreateInstance< T : TDataModule > : TDServerInstance;

....

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