-
Notifications
You must be signed in to change notification settings - Fork 712
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to split code when using inversify js? #1504
Comments
I would say there's not a single way of accomplishing this. This is more an architecture's question rather than an inversify question imo. What is going to be the responsibility of the splitted packages? Are there any asyncronous processes such as the connection to a database? If you determine the responsibility of those packages includes providing some sort of DI mechanism, you'll be probably thinking about DI with hierachical packages. At first glance, every package could provide a container module to be loaded. Having said that, this approach is probably not good enough if you consider inversify. For these reasons I consider NestJs way superior than inversify, at least for this use case: NestJS allow you to create modules able to import other modules and even handle async dependencies through different mechanisms. If you want a hierarchical DI approach and you have any sort of complexity, I would suggest you to use NestJS or a similar DI approach that allow you to establish modules hierarchy. Having said that, maybe a DI hierarchy is not what you want because you only initialize instances in a few packages, the top most ones in the hierarchy, and those packages are really the only ones which need a DI container. In that case, inversify container modules might be good enough for you. What is your use case? The ninja case is simple to understand, but maybe it does not describe the challenges you're facing. |
Thx for your detailed answer. type KatanaProvider = () => Promise<Katana>;
@injectable()
class Ninja implements Ninja {
public shuriken: Shuriken;
public katanaProvider: KatanaProvider;
public constructor(
@inject("KatanaProvider") katanaProvider: KatanaProvider,
@inject("Shuriken") shuriken: Shuriken
) {
this.katanaProvider = katanaProvider;
this.shuriken = shuriken;
}
public async fight() {
const katana = await this.katanaProvider();
return this.katana.hit();
};
public sneak() { return this.shuriken.throw(); };
}
container.bind<KatanaProvider>("KatanaProvider").toProvider<Katana>((context) => {
return async () => {
const Katana = await import('./katana');
let katana = context.container.get<Katana>("Katana");
return katana;
});
};
});
var ninja = container.get<Ninja>("Ninja"); But when does |
@icy0307 Inversify binding process is suposed to be sync by design unless NestJS one, so I think it's not the best library for your case. I would expect that provider not to work properly. In your case, every class binding happens asyncronously. To be honest, DI and fast loading times do not play very well. I'm more in the backend side, but I had a similar problem in a serverless infrastructure: warm times had to be low. If you are aiming to go with the DI strategy you're commenting, I understand you app is huge but that critical part does not have too many dependencies, otherwise this strategy would not work. The approach I would follow would be bundling and pruning. Of course, I would not create a single bundler because your app is huge but, let's assume you have a critical part to be rendered asap and a non critical part. In the most simple scenario, those two parts are totally independent whatsoever. In that case, two bundles solve the problem. I don't think that is your case so, let's asume there's share logic (classes / components) in those two parts. In this case, you will need to create multiple bundles to distribute the shared logic to both of your parts, the critical one and the non critical one. For example:
In this case, I would create the following bundles:
Of course, feel free to use whatever strategy you consider convenient to achieve this. A monorepo with multiple packages with a bundler seems a good way to go. Of course, you know better than me the projject, so maybe there is not a single shared bundle including S1, S2, S3, S4, maybe there're two shared bundles with {S1, S2, NC54} and {S3, S4} because it makes more sense. I hope it helps. Of course, there's not a single way to go and I'm not a frontend expert, but I think the solution is not too bad. Unfortunatelly, we are running off topic, maybe we should discuss this outside an inversify issue |
Take this code for example, how could one import
Shuriken
dynamically to code split?I've been looking into
hierarchical DI systems
,provider injection
, andAsynchronous container modules
, but none seems appropriate.Shuriken
could have other dependencies from di as well. soprovider injection
doesn't fit the bill.hierarchical DI systems
feels like that for every class that is intended to be loaded dynamically, a child container must be created.How to split code in inversify?
The text was updated successfully, but these errors were encountered: