borni69 1 Posted January 25, 2022 (edited) Hi , I have downloaded the delphimvcframework and it look’s great 🙂 thanks to  @Daniele Teti , I have also bought the book 🙂 great reading, recommended. I love this system , but will play more with it next couple of weeks.  A small question.  We have a small webbroker app today running on Apache AWS, we use a globale Dict as a keystore in all requests, and we use FMX data pooling. FMX data pooling seems to be well documented in your book, and I guess I can almost use like before.   If you look at below code we use dict String_Dict as a global variable handled by TMultiReadExclusiveWriteSynchronizer, any suggestion where to put his variable in delphimvcframework to be able to use it in the different controller / actions like FMVC.AddController(TCustomersController);  In our webmodule we have a global variable and we use it with TMultiReadExclusiveWriteSynchronizer from system.sysutil  Example data from from our Webmodule  … public { Public declarations } SettingTemplateClass : TSettingTemplateClass; end: var WebModuleClass: TComponentClass = TWebModule1; String_Dict : TDictionary<string,String > ; string_Dict_Sync : TMultiReadExclusiveWriteSynchronizer; ….. // connecting String_Dict to a setting class unique for each request procedure TWebModule1.WebModuleCreate(Sender: TObject); begin SettingTemplateClass := TSettingTemplateClass.Create SettingTemplateClass.string_Dict_Sync := string_Dict_Sync; SettingTemplateClass.String_Dict := String_Dict; …. end; // a typical request sending string_dict further using settingTemplateClass to the class generating the response via usersession class procedure TWebModule1.WebModule1getlogondataAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); var userSession : TuserSession; ssoInternalClass : TssoInternalClass; companyid : Integer; lsession_data : String; begin companyid := strtointdef( getRequestParamValue (Request , 'companyid' ),0); userSession := TuserSession.create(SettingTemplateClass,getRequestParamValue(request,'token')); try if isSessionValid(Response,userSession) then begin lsession_data :=getRequestParamValue (Request , 'session_data' ); userSession.userSessionData.setSessionData(lsession_data); ssoInternalClass := TssoInternalClass.Create(userSession); try Response.content := ssoInternalClass.getLogonData( companyid ); finally ssoInternalClass.Free; end; end; finally userSession.Free; end; end; ………… initialization String_Dict := TDictionary<string,String >.create ; string_Dict_Sync := TMultiReadExclusiveWriteSynchronizer.Create; finalization String_Dict.Free; string_Dict_Sync.Free; Example using string_dict in class generating the response data below .   string_Dict_Sync.BeginRead; try string_Dict.TryGetValue('severDayNumberString', severDayNumberString ); finally string_Dict_Sync.EndRead; end;   It it possible o do something similar with delphimvcframework,  ? For me it seems like difficult to share data to a controller .. Thanks in advance Edited January 25, 2022 by borni69 Share this post Link to post
Alberto Fornés 22 Posted January 26, 2022 Yes, you can use this in delphimvcframework. I declare such dictionary in the service unit (it's a windows service), or you can put it in a datamodule and create it at program start and destroy at the end. Webmodule can be created and destroyed several times during program execution. Share this post Link to post
borni69 1 Posted January 26, 2022 (edited) 3 hours ago, Alberto Fornés said: Yes, you can use this in delphimvcframework. I declare such dictionary in the service unit (it's a windows service), or you can put it in a datamodule and create it at program start and destroy at the end. Webmodule can be created and destroyed several times during program execution. Thanks, I can create it in a datamodule, but I still do not understand howto get this datamodule all the way down to the controller..  FMVC.AddController(TCustomersController);  Tcustomercontroller is a class created on request ,and the dict is created at startup.  I undestand that I can use/create a datamodule in the controller, but not howto use one created at startup, holding all the data,, normally I would send the dict to my class using a variable. procedure TMyController.GetCustomers ; var lCustomersModule : TMyDataModule ; begin lCustomersModule := TMyDataModule . Create ( nil ) ; try lCustomersModule . QryCustomers . Open () ;  again thanks   I will also try a few options myself... Edited January 26, 2022 by borni69 Share this post Link to post
Alberto Fornés 22 Posted January 26, 2022 36 minutes ago, borni69 said: Thanks, I can create it in a datamodule, but I still do not understand howto get this datamodule all the way down to the controller..  FMVC.AddController(TCustomersController);  Tcustomercontroller is a class created on request ,and the dict is created at startup.  I undestand that I can use/create a datamodule in the controller, but not howto use one created at startup, holding all the data,, normally I would send the dict to my class using a variable. procedure TMyController.GetCustomers ; var lCustomersModule : TMyDataModule ; begin lCustomersModule := TMyDataModule . Create ( nil ) ; try lCustomersModule . QryCustomers . Open () ;  again thanks   I will also try a few options myself... No , this datamodule should be created at start, and always alive, you reference it from your controller (add datamodule unit to controller), and access it through TMultiReadExclusiveWriteSynchronizer. Share this post Link to post
borni69 1 Posted January 26, 2022 12 minutes ago, Alberto Fornés said: No , this datamodule should be created at start, and always alive, you reference it from your controller (add datamodule unit to controller), and access it through TMultiReadExclusiveWriteSynchronizer. OKI thanks alot 🙂 Share this post Link to post
borni69 1 Posted January 27, 2022 21 hours ago, borni69 said: OKI thanks alot 🙂 This is my result from test.. and it seems to work..  unit HseqDmDictU; interface uses System.SysUtils, System.Classes, Generics.collections; type TDataModuleDict = class(TDataModule) private FString_Dict: TDictionary<string, String>; Fstring_Dict_Sync: TMultiReadExclusiveWriteSynchronizer; procedure SetString_Dict(const Value: TDictionary<string, String>); procedure Setstring_Dict_Sync( const Value: TMultiReadExclusiveWriteSynchronizer); { Private declarations } public { Public declarations } destructor Destroy; override; procedure initDict; property String_Dict : TDictionary<string,String > read FString_Dict write SetString_Dict; property string_Dict_Sync : TMultiReadExclusiveWriteSynchronizer read Fstring_Dict_Sync write Setstring_Dict_Sync; end; var DataModuleDict: TDataModuleDict; implementation {%CLASSGROUP 'System.Classes.TPersistent'} {$R *.dfm} { TDataModuleDict } procedure TDataModuleDict.initDict; begin FString_Dict := TDictionary<string,String >.create ; Fstring_Dict_Sync := TMultiReadExclusiveWriteSynchronizer.Create; end; destructor TDataModuleDict.Destroy; begin FString_Dict.Free; Fstring_Dict_Sync.Free; inherited; end; procedure TDataModuleDict.SetString_Dict( const Value: TDictionary<string, String>); begin FString_Dict := Value; end; procedure TDataModuleDict.Setstring_Dict_Sync( const Value: TMultiReadExclusiveWriteSynchronizer); begin Fstring_Dict_Sync := Value; end; end.  On my console app startup init the Datamodule (not sure for Linux where I will put it, but will try later)  begin ReportMemoryLeaksOnShutdown := True; IsMultiThread := True; // Prepare Dict DataModuleDict:= TDataModuleDict.Create(nil); try DataModuleDict.initDict; // Important try if WebRequestHandler <> nil then WebRequestHandler.WebModuleClass := WebModuleClass; WebRequestHandlerProc.MaxConnections := 1024; RunServer(8080); except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; finally DataModuleDict.Free; end; end.  Using dict in code from  seperate unit  unit DictU; interface uses system.sysutils , system.classes ,DataConU, Generics.collections , TemplateRecordU; type TDictClassV2 = Class ( Tobject ) private public procedure saveString ( akey , avalue : String ) ; function loadString ( akey : String ) :String; End; implementation uses HseqDmDictU; { TDictClassV2 } function TDictClassV2.loadString(akey: String): String; begin result:=''; DataModuleDict.string_Dict_Sync.BeginRead; try DataModuleDict.string_Dict.TryGetValue(akey,result); finally DataModuleDict.string_Dict_Sync.EndRead; end; end; procedure TDictClassV2.saveString(akey, avalue: String); begin DataModuleDict.string_Dict_Sync.BeginWrite; try try if not DataModuleDict.String_Dict.ContainsKey(akey) then DataModuleDict.String_Dict.Add(akey,avalue); Except on E : Exception do begin // logg error end; end; finally DataModuleDict.string_Dict_Sync.EndWrite; end; end; end.  If you would do it differently please let me know Thanks again... Share this post Link to post