You are not logged in.
Pages: 1
@ab
i m learning how to control mORMot, not sure any wrong with my code:
program Project1;
{$APPTYPE CONSOLE}
uses
mORMot, mORMotSQLite3, SynSQLite3Static, System.SysUtils;
type
IRemote = interface(IInvokable)
['{48FCB3D5-0992-48A4-ACFD-13FE652802FB}']
function TestOK: TID;
function TestError: TID;
end;
TRemote = class(TInterfacedObject, IRemote)
private
fClient: TSQLRestClientDB;
public
procedure AfterConstruction; override;
function TestOK: TID;
function TestError: TID;
end;
var
rServer, lServer: TSQLRestServerDB;
rClient: TSQLRestClientDB;
fRemote: IRemote;
procedure TRemote.AfterConstruction;
begin
inherited;
fClient := TSQLRestClientDB.Create(lServer);
end;
function TRemote.TestOK: TID;
var
aContext: TSQLRestServerURIContext;
begin
aContext := ServiceContext.Request;
fClient.ServerTimeStampSynchronize;
ServiceContext.Request := aContext;
result := ServiceContext.Request.SessionUser;
end;
function TRemote.TestError: TID;
begin
fClient.ServerTimeStampSynchronize;
//ServiceContext.Request=nil here
result := ServiceContext.Request.SessionUser;
end;
begin
lServer := TSQLRestServerDB.Create(TSQLModel.Create([]), 'local.db3', false);
lServer.CreateMissingTables();
rServer := TSQLRestServerDB.Create(TSQLModel.Create([]), 'remote.db3', true);
rServer.CreateMissingTables();
rServer.ServiceRegister(TRemote,[TypeInfo(IRemote)],sicClientDriven);
rClient := TSQLRestClientDB.Create(rServer);
rClient.SetUser('User', 'synopse');
rClient.ServiceRegisterClientDriven(TypeInfo(IRemote), fRemote);
Writeln('TestOK result: ');
Writeln(fRemote.TestOK);
try
Writeln('TestError result: ');
Writeln(fRemote.TestError);
except
on E: Exception do
writeln(E.Message);
end;
readln;
end.
console output
TestOK result:
3
TestError result:
TInterfacedObjectFakeClient.FakeCall(IRemote.TestError) failed: '{
"errorCode":500,
"error":
{"EAccessViolation":{"EAccessViolation":"Access violation at address 00660ADF in
module 'Project1.exe'. Read of address 00000120"}}
}'
Last edited by Wideyu (2015-12-11 09:44:37)
Offline
I guess this is because you may be mixing things up.
fClient.ServerTimeStampSynchronize is also a client call, so the ServiceContext is reset when fClient.ServerTimeStampSynchronize finishes.
Some other points:
- Do not use TInterfacedObject and override AfterConstruction: use TInterfacedObjectWithCustomCreate or TInterfacedObjectAutoCreateFields, and override the virtual Create constructor;
- You are using a global variable to locale the main server, this is not SOLID at all.
To make proper IoC:
- Use ServiceContext.Request.Server to access the server instance directly;
- Define some server-side SOA services, then inherit your TRemote service from TInjectableObject, and all needed services as published interface properties: any interface published property would be automatically injected when the TRemote instance would be created.
Offline
Thanks for proper points and IoC. But Need some pratice to understand TInterfacedObjectWithCustomCreate or TInterfaceObjectAutoCreateFields and TInjectableObject
Indeed fClient used as a proxy to fetch data from lServer, to feed TRemote@rServer to the rClient. I m confused why fClient clear the rServer's serviceContext?
Offline
Pages: 1