Ce n'est pas vraiment une injection de dépendance, mais plutôt une localisation de service : vos autres modules demandent une "classe" par une chaîne de caractères "clé", et obtiennent en retour une instance de celle-ci que le "localisateur de service" (dans ce cas RequireJS) a été câblé pour leur fournir.
L'injection de dépendances consisterait à renvoyer le MyModel
constructeur, c'est-à-dire return MyModel
puis dans un centre composition Racine en injectant une instance de MyModel
dans d'autres instances. J'ai mis en place un exemple de ce fonctionnement ici : https://gist.github.com/1274607 (également cité ci-dessous)
De cette façon, la racine de composition détermine si elle doit distribuer une seule instance de MyModel
(i.e. le rendre singleton scoped) ou de nouveaux pour chaque classe qui le requiert (instance scoped), ou quelque chose entre les deux. Cette logique n'appartient ni à la définition de MyModel, ni aux classes qui en demandent une instance.
(Note annexe : bien que je ne l'ai pas utilisé, wire.js est un conteneur d'injection de dépendances à part entière pour JavaScript qui a l'air plutôt cool).
Vous n'abusez pas nécessairement de RequireJS en l'utilisant comme vous le faites, bien que ce que vous faites semble un peu détourné, c'est-à-dire déclarer une classe et retourner une nouvelle instance de celle-ci. Pourquoi ne pas simplement faire ce qui suit ?
define(function () {
var value = 10;
return {
doStuff: function () {
alert(value);
}
};
});
L'analogie qui vous échappe peut-être est que les modules sont équivalents à des "espaces de noms" dans la plupart des autres langages, même s'il s'agit d'espaces de noms auxquels vous pouvez attacher des fonctions et des valeurs. Ils ne sont pas équivalents aux classes, bien que, comme vous l'avez montré, vous puissiez rendre les exportations d'un module égales à celles d'une instance de classe donnée.
Vous pouvez donc créer des singletons en attachant des fonctions et des valeurs directement au module, mais c'est un peu comme créer un singleton en utilisant une classe statique : c'est très peu flexible et ce n'est généralement pas la meilleure pratique. Cependant, la plupart des gens traitent leurs modules comme des "classes statiques", parce que l'architecture correcte d'un système d'injection de dépendances exige beaucoup de réflexion dès le départ, ce qui n'est pas vraiment la norme en JavaScript.
Voici https://gist.github.com/1274607 en ligne :
// EntryPoint.js
define(function () {
return function EntryPoint(model1, model2) {
// stuff
};
});
// Model1.js
define(function () {
return function Model1() {
// stuff
};
});
// Model2.js
define(function () {
return function Model2(helper) {
// stuff
};
});
// Helper.js
define(function () {
return function Helper() {
// stuff
};
});
// composition root, probably your main module
define(function (require) {
var EntryPoint = require("./EntryPoint");
var Model1 = require("./Model1");
var Model2 = require("./Model2");
var Helper = require("./Helper");
var entryPoint = new EntryPoint(new Model1(), new Model2(new Helper()));
entryPoint.start();
});