@@ -10,8 +10,182 @@ Application Contexts and Dependency Injection
1010<a name =" intro " >Introduction</a >
1111--------------------------------
1212
13- A familiar application context and dependency injection package, supporting simple
13+ A familiar application context and dependency injection package for JavaScript , supporting simple
1414singleton and prototype component factory definitions, with a choice of manual or auto
1515wiring (injection) of property references and config placeholders.
1616
17+ <a name =" usage " >Usage</a >
18+ --------------------------------
19+
20+ ### Singleton Components
21+
22+ To configure a simple singleton service object, simply instantiate an ` ApplicationContext ` and pass it
23+ the class definition. The default scope is ` singleton ` , and the component name defaults to lowerCamelCase
24+ of the class name.
25+
26+ ``` javascript
27+ const { ApplicationContext } = require (' @alt-javascript/cdi' );
28+ const { SimpleClass } = require (' .' );
29+
30+ const applicationContext = new ApplicationContext (SimpleClass);
31+ applicationContext .start ();
32+ applicationContext .get (' simpleClass' );
33+ ```
34+ Simple types, objects and functions can be registered as components.
35+
36+ ``` javascript
37+ const { ApplicationContext } = require (' @alt-javascript/cdi' );
38+ const { SimpleClass } = require (' .' );
39+
40+ const applicationContext = new ApplicationContext ([
41+ {name: ' someData' , attr: ' aValue' , behave : () => {}},
42+ {Reference : (what ) => { console .log (` Hello ${ what} ` )},
43+ name : ' aFunc' }]);
44+ applicationContext .start ();
45+ applicationContext .get (' someData' ).behave ();
46+ applicationContext .get (' aFunc' )(' world!' );
47+ ```
48+
49+ Singletons can also be defined with the common alias names ` Service ` ,` Component ` and ` Singleton `
50+
51+ ``` javascript
52+ const { ApplicationContext , Singleton , Service , Component } = require (' @alt-javascript/cdi' );
53+ const { SimpleSingleton , SimpleService , SimpleSingleton } = require (' .' );
54+
55+ const context = new Context ([
56+ new Singleton (SimpleSingleton),
57+ new Service (SimpleService),
58+ new Component (SimpleSingleton)]);
59+ const applicationContext = new ApplicationContext ([context]);
60+ applicationContext .start ();
61+ applicationContext .get (' simpleSingleton' );
62+ applicationContext .get (' simpleService' );
63+ applicationContext .get (' simpleComponent' );
64+ ```
65+ ### Prototype (transient) Components
66+
67+ Prototype, or transient scoped objects can be defined with Prototype definition, or Transient definition. These
68+ objects are created each time they are requested from the context, or wired by the context lifecycle.
69+
70+ ``` javascript
71+ const { ApplicationContext , Prototype , Transient } = require (' @alt-javascript/cdi' );
72+ const { SimpleClass , SimpleTransient } = require (' .' );
73+
74+ const applicationContext = new ApplicationContext (new Prototype (SimpleClass));
75+ const applicationContext = new ApplicationContext (new Transient (SimpleTransient));
76+ applicationContext .start ();
77+ applicationContext .get (' simpleClass' );
78+ ```
79+
80+ ### Explicit Component Definitions
81+
82+ Use the Component class to declare the full explicit definition of a component, allow full control.
83+
84+ ``` javascript
85+ const { ApplicationContext , Component } = require (' @alt-javascript/cdi' );
86+ const { SimpleClass , SimpleTransient } = require (' .' );
87+
88+ const applicationContext = new ApplicationContext (
89+ new Component ({
90+ Reference : SimpleClass,
91+ name : ' useAnExplicitName' ,
92+ qualifier : ' @my-scope/SimpleClass' ,
93+ scope : Scopes .SERVICE ,
94+ }));
95+
96+ applicationContext .start ();
97+ applicationContext .get (' useAnExplicitName' );
98+ ```
99+
100+ ### Component Factory Definitions
101+
102+ A component can be created by referencing a factory function directly.
103+
104+ ``` javascript
105+ const { ApplicationContext , Component } = require (' @alt-javascript/cdi' );
106+ const { MyClass } = require (' .' );
107+
108+ const applicationContext = new ApplicationContext (
109+ new Component ({
110+ factory : MyClass .someStaticFunction (),
111+ name : ' fromAFactory' ,
112+ qualifier : ' @my-scope/SimpleClass' ,
113+ scope : Scopes .SERVICE ,
114+ }));
115+
116+ applicationContext .start ();
117+ applicationContext .get (' useAnExplicitName' );
118+ ```
119+ ### Component Property Injection (wiring)
120+
121+ Component properties are autowired by name, by default. In the example ` classB ` and ` classC ` will be autowired,
122+ but ` classD ` , which is non-null will be let alone. The ` attribute ` will remain null if not found in the application
123+ context.
124+
125+ ``` javascript
126+ module .exports = class ClassA {
127+ constructor () {
128+ this .classB = null ;
129+ this .classC = ' autowired' ;
130+ this .classD = new new ClassD ();
131+ this .attribute = null ;
132+ }
133+ };
134+ ```
135+
136+ Configuration values that are booted with ` @alt-javascript/boot ` are injected with the familiar placeholder syntax.
137+
138+ ``` javascript
139+ module .exports = class ClassA {
140+ constructor () {
141+ this .attribute = ' ${get.this.from.config}' ;
142+ }
143+ };
144+ ```
145+
146+ ### Advanced Component Property Injection, factory and wireFactory functions
147+
148+ Properties can be injected, directly from functions, or from references to functions on other components using
149+ the explicit ` Property ` declaration class.
150+
151+ ``` javascript
152+ const context = new Context ([
153+ {
154+ name: ' singletonFactory' ,
155+ generator : (param ) => ({ name: ' simplePrototype' , attr: param }),
156+ },
157+ new Service ({
158+ Reference: ' MyServiceService' ,
159+ properties: [new Property ({
160+ name: ' myServiceProperty' ,
161+ factory: ' singletonFactory' ,
162+ factoryFunction: ' generator' ,
163+ factoryArgs: ' one' })]
164+ })]);
165+
166+ const applicationContext = new ApplicationContext ([context]);
167+ applicationContext .start ();
168+ const myServiceService = applicationContext .get (' myServiceService' );
169+ assert .exists (myServiceService, ' myServiceService exists' );
170+ assert .equal (myServiceService .myServiceProperty .attr , ' one' , ' myServiceService.myServiceProperty.attr == one' );
171+ ```
172+
173+ Where the context of the target component being wired is required, a ` wireFactory ` can be declared on a ` prototype `
174+ and the target ` Component ` instance is passed as an argument by default. The ` ApplicationContext ` declares a
175+ ` logger ` prototype with the ` loggerFactory ` component as the ` wireFactory ` , allowing the component qualifier to be
176+ used as the logger category (true).
177+
178+ ### Global components:
179+
180+ The ApplicationContext is designed to play nicely with other projects in the ` @alt-javascript ` scope, so the
181+ booted ` config ` , ` loggerFactory ` , ` logger ` , ` loggerCategoryCache ` are available.
182+
183+ Any component declared with a ` logger ` and ` qualifier ` properties will be injected with an appropriate logger,
184+ as if by _ magic_ .
185+
186+ <a name =" license " >License</a >
187+ -----------------------------
188+
189+ May be freely distributed under the [ MIT license] ( https://raw.githubusercontent.com/craigparra/alt-logger/master/LICENSE ) .
17190
191+ Copyright (c) 2021 Craig Parravicini
0 commit comments