Passing a user-defined parameter to a web server entry point without using global variables.
Added by George McFie over 3 years ago
I would like to pass a custom (user-defined) variable to my web site entry point without having to use global variables.
For example, my entry code looks something like the following ...
namespace
{
const Setup* globalSetup = nullptr; // <<<<<<<<<<<<< Ugly global variable
}
std::unique_ptr<Wt::WApplication> CreateApplication (const Wt::WEnvironment& environment)
{
auto application = Wt::cpp14::make_unique<Wt::WApplication> (environment);
...
application->root()->addWidget (Wt::cpp14::make_unique<Roster> (application.get(), environment, *globalSetup)); // <<<<<<<< Global used here
return application;
}
class WebServer : public Wt::WServer
{
public:
WebServer (const Setup& setup, int argc, char* argv[]);
virtual ~WebServer() override = default;
...
};
WebServer::WebServer (const Setup& setup, int argc, char* argv[])
: Wt::WServer (argc, argv, WTHTTP_CONFIGURATION)
{
globalSetup = &setup;
Wt::WServer::addEntryPoint (Wt::EntryPointType::Application, CreateApplication);
}
Is there a clean way to do this without using the intermediate 'globalSetup' global?
Replies (3)
RE: Passing a user-defined parameter to a web server entry point without using global variables. - Added by Stefan Bn over 3 years ago
I would say this is rather a general C++ software architecture question than a Wt question.
Depending on what your app does, usually you will have some kind of data persistence layer/mechanism to handle configuration data or data that the app user generates, such as a SQL database, INI files or just hard coded data storage in your code.
You could check the Blog example in wt/examples/blog to see how data persistence is done using good practice 'Model-View-Controller' pattern between Wt classes.
Regarding your const Setup* globalSetup = nullptr;
: with Wt I felt in love with the Json::Object data representation, since it's easy to create/read, pass around and persist to database/any file.
RE: Passing a user-defined parameter to a web server entry point without using global variables. - Added by Rathnadhar K V over 3 years ago
Namaskara,
Its very easy to do it....
Here is how i did it...
-----------------------------------------------------------------------------------------------------------------Header file
class web_application : public Wt::WApplication
{
private:
CONST_SESSION_UNIQUE_HANDLE_REF web_session_unique_handle_ref;
public:
web_application(const Wt::WEnvironment& env,
CONST_SESSION_UNIQUE_HANDLE_REF session_unique_handle_ref
);
};
}
----------------------------------------------------------------------------------------------------------------src file
web_application::web_application(const Wt::WEnvironment& env,
CONST_SESSION_UNIQUE_HANDLE_REF session_unique_handle_ref
)
: Wt::WApplication{env},
web_session_unique_handle_ref{session_unique_handle_ref}
{
..... Your code here....
}
int main(int argc, char **argv)
{
try
{
LOG(INFO) << fmt::format(
"\n┌{0:─^{2}}┐\n"
"│{1: ^{2}}│\n"
"└{0:─^{2}}┘\n",
"",
"Wt Web Server",
39
);
Wt::WServer server{argc, argv, WTHTTP_CONFIGURATION};
//ctor of session has configuration logic too.....
auto session_unique_handle = std::make_unique<Session>("session.db"); //creating and connecting to the database
server.addEntryPoint(Wt::EntryPointType::Application,
[&](const Wt::WEnvironment& env)
{
return std::make_unique<web_application>(env,
session_unique_handle
);
},
NULL_STRING,
"resources/icons/favicon.ico"
);
//Get set and GO!!!
server.run();
}
catch(exception& dex)
{
LOG(ERROR) << dex.what();
exit(1);
}
exit(0);
}
Hope it helps...
RE: Passing a user-defined parameter to a web server entry point without using global variables. - Added by George McFie over 3 years ago
Ah, yes of course! I don't know why I didn't think to use a lambda.
Thanks Namaskara - nice solution.