0

I use inversify and I have some code that looks like this:

export const bindings = new AsyncContainerModule(async (bind) => {

await require("./controllers/BaseController");
await require("./controllers/ContentController");

bind<CssLoader>(TYPE.CssLoader).to(CssLoader).inSingletonScope();
bind<GQLQueryLoader>(TYPE.GQLQueryLoader).to(GQLQueryLoader).inSingletonScope();
bind<GQLRepository>(TYPE.GQLRepository).to(GQLRepository).inSingletonScope();
bind<ArticleRenderer>(TYPE.ArticleRenderer).to(ArticleRenderer).inSingletonScope();
bind<GuideRenderer>(TYPE.GuideRenderer).to(GuideRenderer).inSingletonScope();
bind<RendererFactory>(TYPE.RendererFactory).to(RendererFactory).inSingletonScope();
bind<HeaderAndFooterManager>(TYPE.HeaderAndFooterManager).to(HeaderAndFooterManager).inSingletonScope();});

My problem is that I need the HeaderAndFooterManager to be registered only after the GQLQueryLoader is registered, because it uses the queries only after they are loaded.

The container is used in the app like this:

(async () => {
const staticServer = express();
staticServer.use(express.static(path.join(__dirname, 'public')));

staticServer.engine('handlebars', exphbs({  }));
staticServer.set('view engine', 'handlebars');
staticServer.set('views', path.join(__dirname, '..', 'views'));


const PORT = process.env.PORT || 3000;
const container = new Container();
await container.loadAsync(bindings);

const app = new InversifyExpressServer(container, null, null, staticServer);
const server = app.build();

server.listen(PORT, () => {
    console.log(`Server running on port ${PORT}/`)
}); })();

Edit>>> Tthe problem is that both services need to initialize some state in constructor when the server starts. GQLQueryLoader needs to load the queries from disk and provide access to them, so I do not have to read from disk at each request, and HeaderAndFooterManager needs to perform some queries in the constructor, in order to cache the result on server start, so that I keep that info in memory, but it needs access to GQLQueryLoader loaded queries. What I did is not to initialize the header and footer data until it is needed the first time. I check if is loaded, if not I load it. However, this is just a workaround, and it feels it is the kind of problem that is important to know how to solve in a clean way.

Ovidiu Badita
  • 133
  • 10
  • Did you mean that you want create an instance of `HeaderAndFooterManager` after instance of `GQLQueryLoader` is created because binding means its register. Or in other wordfs what do you mean by `register`? – Xesenix Jun 26 '19 at 21:58
  • Yes, binding is register. I want the HeaderAndFooterManager to be registered only after the async actions from GQLQueryLoader will finish. I have solved the problem by not initializing the HeaderAndFooterManager the way I wanted, but instead I will have it boot once it is used, but that makes me use more local state than I would like. What I did is a workaround, not a solution. I have seen the providers in documentation, but it is not clear yet how I should use them without changing the services that I already have.,, I hope I will find eventually an elegant solution for this problem. – Ovidiu Badita Jun 27 '19 at 08:10
  • 1
    Yes im also using i call them `boot:provider` where I define provider that is ran on application boot you can take a look here maybe its not best solution but can give you some ideas: https://github.com/Xesenix/ludumdare-43/blob/master/game/app/app.module.tsx#L114 here how its added to list of boot providers https://github.com/Xesenix/ludumdare-43/blob/master/src/lib/i18n/i18n.module.ts#L28 and here how it may look like https://github.com/Xesenix/ludumdare-43/blob/master/src/lib/i18n/i18n-boot.provider.ts – Xesenix Jun 27 '19 at 11:07

0 Answers0