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两个方法
没有评论:
发表评论