procedure TServerContainer1.DSServerClass1GetClass( DSServerClass: TDSServerClass; var PersistentClass: TPersistentClass); begin PersistentClass := ServerMethodsUnit1.TServerMethods1; end;问题是:一般的真实应用里,我们的服务方法类会有很多,岂不是要在TServerContainer里面放很多个 TDSServerClass??? 并且还要去写它的OnGetClass类方法
要想解决这个问题,我们还是的理解TDSServerClass到底是干嘛的,为啥EMBT这么设计了。
datasnap里面,TDSServer是老大,它靠TDSTCPServerTransport来负责通讯, 至于根据通讯来触发的什么服务器方法,就靠TDSServer了。TDSServer将它所拥有的TDSServerClass的TPersistentClass的服务方法都给存起来,代码在
DSCommonServer.pas的
procedure TDSServerMethodProvider.AddRegisteredServerClasses;
var
List: TDBXArrayList;
Index: Integer;
Count: Integer;
ServerClass: TDSCustomServerClass;
ClassInfo: TDSClassInfo;
DsClass: TDSClass;
AdapteeClass: TDSClass;
ClassName: UnicodeString;
begin
List := TDBXArrayList.Create;
try
FServer.GetServerClassList(List);//取得DSServer关联着的TDSServerClass列表
Count := List.Count;
for index := 0 to Count - 1 do
begin
ServerClass := TDSCustomServerClass(List[Index]);
DsClass := ServerClass.DSClass; //这里触发了通过GetDSClass函数触发OnGetClass事件
ClassName := DsClass.DSClassName;
AdapteeClass := DsClass.AdapteeDSClass;
if AdapteeClass <> nil then
ClassName := AdapteeClass.DSClassName;
ClassInfo := TDSClassInfo.Create;
ClassInfo.ServerClass := ServerClass;
ClassInfo.DSClassName := ClassName;
ClassInfo.LifeCycle := ServerClass.LifeCycle;
ClassInfo.RoleName := ServerClass.RoleName;
ClassInfo.DSClass := DsClass;
AddServerClass(ClassInfo);//存起来
AddAllMethods(ClassInfo); //存起来
end;
finally
FreeAndNil(List);
end;
end;
进一步查看代码知道,TDSServerClass的GetDSClass是可以重载的function GetDSClass: TDSClass; override;因此,如果我们自己要写很多服务方法类时,可以自己写一个注册服务方法的类,也就是直接覆盖GetDSClass就可以了,那样就不必写什么OnGetClass事件并去关联事件(这里另一个想法是,要关联事件,直接用匿名函数去关联,这样就不必为了关联而单独定义一个类方法,但是匿名函数只是一个方法,而不是对象方法,也要让MakeObjectInstance反向?等几天测测)。
简单的代码如下
{$METHODINFO ON}
TMyServerMethod = class
end;
{$METHODINFO OFF}
TServerMethodA = class(TMyServerMethod )
function ServerMethodA1: Integer;
function ServerMethodA2: Integer;
end;
TServerMethodB = class(TMyServerMethod)
function ServerMethodB1: Integer;
function ServerMethodB2: Integer;
end;
TMyDSServerClass=class(TDSServerClass)
private
FPersistentClass: TPersistentClass;
protected
function GetDSClass: TDSClass; override;
public
constructor Create(AOwner: TComponent; AServer: TDSCustomServer; AClass: TPersistentClass); reintroduce;overload;
end;
constructor TMyDSServerClass.Create(AOwner: TComponent; AServer: TDSCustomServer; AClass: TPersistentClass);
begin
inherited Create(AOwner);
FPersistentClass := AClass;
Self.Server := AServer;
end;
function TMyDSServerClass.GetDSClass: TDSClass;
begin
Result := TDSClass.Create(FPersistentClass, False);
end;
然后,我们要注册服务方法类时,写个注册函数procedure RegisterServerClasses(AOwner: TComponent; AServer: TDSServer); begin TMyDSServerClass.Create(AOwner, AServer, TServerMethodA ); TMyDSServerClass.Create(AOwner, AServer, TServerMethodB); end;有了这个函数,我们以后写代码,就可以自己专注写服务方法类,写完了再在这里增加一行代码就行了,代码不用拥挤到一个ServerContainerUnit1里,不好维护。
当然,DSServer还有LifeCycle的属性,可以添加后,覆盖CreateInstance和DestroyInstance两个方法
没有评论:
发表评论