08-22-2020, 02:11 PM
(This post was last modified: 08-22-2020, 02:13 PM by Alexandre Machado.)
Hi Bruce,
Let's start with UserSession and related stuff:
TIWUserSession is the class declared in unit UserSessionUnit.pas. When you create a new IW application, a new UserSessionUnit.pas file is automatically created for you by IW Application Wizard.
UserSession is a function declared in unit ServerController. The function UserSession returns the TIWUserSession instance for that specific session.
Remember that when you have "N" users (sessions) using your application, you also have "N" instances of TIWUserSession class, each one belonging to a specific application user session.
So, when you call the function UserSession from your code, you will always get the TIWUserSession instance for the current session, no need to worry about it because IW will take care of the complications for you.
The same instance is also stored in the property named "Data" of TIWApplication.
That's why
WebApplication.Data = UserSession() // remember -> UserSession() here is the function declared in ServerController.pas
Personally I wouldn't create anything named TUserSession because I find it very confusing with existing TIWUserSession and UserSession() already declared in every IntraWeb application.
I would definitely look for another name....
Also, I personally like to make my DataModules available through existing TIWUserSession, as properties. Like this:
Please notice that here I'm creating the DataModule on demand, i.e. it will be instantiated only when referenced the first time. Also important to notice that the owner of the DataModule is always the UserSession itself. This has 2 advantages: (a) I don't need to write code to free it and (b) IntraWeb will take care of freeing it for me when destroying the session.
Also, doing that way, the DataModule1 can be referenced from anywhere in my application like this:
Which makes it vary handy.
Another thing I do all the time is connecting DataSources and DataSets (in my DataModule1, for instance), via code, inside OnCreate events of IWForms. So I have:
This has 2 main advantages: (a) Makes sure that my components are always connected (sometimes you save a form and it loses the reference to another component in another container) and (b) it performs better when creating the form because the code which loads the form from DFM doesn't have to find the component in another DataModule and connect them.
Organizing your application this way I find it very hard to have anything crashing because the lifetime of all objects is handled by IntraWeb itself, with zero user code.
Let's start with UserSession and related stuff:
TIWUserSession is the class declared in unit UserSessionUnit.pas. When you create a new IW application, a new UserSessionUnit.pas file is automatically created for you by IW Application Wizard.
UserSession is a function declared in unit ServerController. The function UserSession returns the TIWUserSession instance for that specific session.
Remember that when you have "N" users (sessions) using your application, you also have "N" instances of TIWUserSession class, each one belonging to a specific application user session.
So, when you call the function UserSession from your code, you will always get the TIWUserSession instance for the current session, no need to worry about it because IW will take care of the complications for you.
The same instance is also stored in the property named "Data" of TIWApplication.
That's why
WebApplication.Data = UserSession() // remember -> UserSession() here is the function declared in ServerController.pas
Personally I wouldn't create anything named TUserSession because I find it very confusing with existing TIWUserSession and UserSession() already declared in every IntraWeb application.
I would definitely look for another name....
Also, I personally like to make my DataModules available through existing TIWUserSession, as properties. Like this:
Code:
type
TIWUserSession = class(TIWUserSessionBase)
private
{ Private declarations }
FDataModule1: TDataModule1;
function GetDataModule1: TDataModule1;
public
{ Public declarations }
property DataModule1: TDataModule1 read GetDataModule1;
end;
implementation
{$R *.dfm}
{ TIWUserSession }
function TIWUserSession.GetDataModule1: TDataModule1;
begin
if not Assigned(FDataModule1) then
FDataModule1 := TDataModule1.Create(Self);
Result := FDataModule1;
end;
Please notice that here I'm creating the DataModule on demand, i.e. it will be instantiated only when referenced the first time. Also important to notice that the owner of the DataModule is always the UserSession itself. This has 2 advantages: (a) I don't need to write code to free it and (b) IntraWeb will take care of freeing it for me when destroying the session.
Also, doing that way, the DataModule1 can be referenced from anywhere in my application like this:
Code:
dm := TIWUserSession(WebApplication.Data).DataModule1; // using WebApplication which is a property of many controls, IWForm, etc.
or
dm := UserSession.DataModule1; // using UserSession() function from ServerController.pas, which must be added to the uses clause
Which makes it vary handy.
Another thing I do all the time is connecting DataSources and DataSets (in my DataModule1, for instance), via code, inside OnCreate events of IWForms. So I have:
Code:
TIWForm1 = class(TIWAppForm)
private
FDataModule1: TDataModule1;
public
end;
implementation
{$R *.dfm}
procedure TIWForm1.IWAppFormCreate(Sender: TObject);
begin
FDataModule1 := TIWUserSession(WebApplication.Data).DataModule1; // or UserSession.DataModule1 if you add ServerController to the uses clause
DataSource1.DataSet := FDataModule1.Query1;
DataSource2.DataSet := FDataModule1.Query2;
DataSource3.DataSet := FDataModule1.Query3;
// and so on
end;
This has 2 main advantages: (a) Makes sure that my components are always connected (sometimes you save a form and it loses the reference to another component in another container) and (b) it performs better when creating the form because the code which loads the form from DFM doesn't have to find the component in another DataModule and connect them.
Organizing your application this way I find it very hard to have anything crashing because the lifetime of all objects is handled by IntraWeb itself, with zero user code.