| 资源简介: |
重要概念: 这种机制的思想是把调用方、实现方之间的 命令调度层 独立出来(为了更好的关注业 务功能的实现), 形成一个CommandCenter的东西。 现在是用MIDAS技术实现了这个调度中心的远程调度功能, 如果有空可以用COM+,CORBA 甚至是Socket来实现具有远程调度功能的命令调度层。 【使用方法】 客户端 1.加入工程 uCommand, uData 2.在使用的单元里 uses uCommand 3.在使用的地方 with ICommand(TCommand.Create) do begin Command := 调用命令名称(自定义); Parameters[参数名1(自定义)].AsString := '参数值'; Parameters[参数名2(自定义)].AsInteger := 参数值; Parameters[参数名3(自定义)].AsInteger := Today; if Execute() then begin s := Result[返回结果参数名1(自定义)].AsString; s := Result[返回结果参数名2(自定义)].AsString; ... end else ShowMessage('命令未被执行'); end; 4.基于MIDAS, 跨进程、跨机器调用的用法完全相同, 只要在之前配置一下服务端 如下: CommandCenter.ConfigServer(服务器名或地址, 服务端RDM对象名); 服务端(可以是任何地方: 跨单元,跨DLL,跨进程,跨机器) 1.加入工程 uCommand, uData 2.在需要给调用方提供命令服务的地方定义自己的方法 procedure 方法(const ACommand: ICommand); begin ... end; 并在窗体Create或单元初始化事件中注册该方法, 如下: CommandCenter.RegProc(方法, 自定义的调用命令名称); 这样客户端在调用该命令名称时, 会自动执行服务端方法的代码 3.基于MIDAS, 在RemoteDataModule中(必须是MultiInstance,Apartment线程模式创建的RDM) a.先 uses uCommand b.再在RDM的Create事件中加入如下一行代码: TMidasCommandDSP.Create(Self); 这样就把本RDM和CommandCenter绑定上了, 所有命令将会自动调度 客户端DataSet使用方法 1.将已有的ClientDataSet绑定至Command.DataSet属性上 with ICommand(TCommand.Create) do begin Command := 调用命令名称(自定义); DataSetPurpose := rpQuery; //请求返回查询结果 DataSet := cdsClient; //给DataSet属性绑定一个已有的CDS控件(会自动设Provider) Execute(); //执行完毕后,返回的结果就自动存在cdsClient中了 ... Clear(); //清命令,重新开始一个新命令 Command := 新命令名(自定义); DataSetPurpose := rpUpdate; //请求更新数据 DataSet := AClientDataSet; //给DataSet属性设定为一个CDS控件 Execute(); //这种情况下会自动调用ApplyUpdates end; 以上方法是在Execute之前,设定需要返回结果或更新数据的CDS控件 2.当然,也可以事先不设定DataSet属性,它就会自动创建CDS返回至DataSet属性中, 如下: with ICommand(TCommand.Create) do begin Command := 调用命令名称(自定义); DataSet := nil; //初始为空,可以不设置 DataSetPurpose := rpQuery; //请求返回查询结果DataSet Execute(); DataSource1.DataSet := DataSet; //结果集自动生成,可直接赋给数据感知控件 ... Clear(); //清命令(放心,不会清DataSet) Command := 新命令名(自定义); DataSetPurpose := rpUpdate; //请求更新当前DataSet中的数据 Execute(); //这种情况下会自动调用ApplyUpdates end; 由于Command.DataSet使用的是内部的ClientDataSet池的CDS,即使Command释放后, 外部引用的该DataSet仍然可以被使用。 3.还可以通过CDS.Data传数据的方法来使用 如下: with ICommand(TCommand.Create) do begin Command := 调用命令名称(自定义); DataSetPurpose := rpQuery; //请求返回查询结果DataSet Execute(); cdsClient.Data := TClientDataSet(DataSet.Data) //以后只用访问cdsClient即可 ... end; 这种方法客户端和服务端只用维持一个Command创建的连接就可以搞定所有访问, 以节省 服务端的资源。(关于如何使用最能节省MIDAS服务端资源, 有待深入探讨...) 特别提示: MIDAS服务端采用MultiInstance,Apartment线程模式, 所以服务端的实现方法会自动 被独立线程调用执行, 因此在实现方法中需要自己考虑是否应该保护线程安全。 另外,本地调用还支持 独立线程执行方式,后台线程队列(排队)执行方式。 而跨DLL调用,需要将DLL中的CommandCenter设置为主进程的CommandCenter实例,也就是 要共享调度中心CommandCenter,另外可能还需要共享内存管理器 |