1 /++ 2 Aedi, a dependency injection framework. 3 4 Aedi is a dependency injection framework. It does provide a set of containers that do 5 IoC, and an interface to configure application components (structs, objects, etc.) managed by framework. 6 7 Aim: 8 The aim of library is to provide a dependency injection solution that is 9 feature rich, easy to use, easy to learn, and easy to extend up to your needs. 10 11 Usage: 12 The process of configuring components using Aedi consists of following steps: 13 14 $(UL 15 $(LI Create a container ) 16 $(LI Register an application component. ) 17 $(LI Bind dependencies to it. ) 18 $(LI Repeat process for other components. ) 19 $(LI Boot container, and use components from it ) 20 $(LI Shutdown container ) 21 ) 22 23 Following code example shows how can a IoC container be configured and used: 24 25 ------------------- 26 module app; 27 28 import aermicioi.aedi; 29 import std.stdio; 30 31 /** 32 A struct that should be managed by container. 33 **/ 34 @component 35 struct Color { 36 @setter(cast(ubyte) 255) 37 ubyte r; 38 39 @setter(cast(ubyte) 10) 40 ubyte g; 41 42 @setter(cast(ubyte) 10) 43 ubyte b; 44 } 45 46 /** 47 Size of a car. 48 **/ 49 @component // Register component using annotations 50 struct Size { 51 52 @setter(200UL) // Set property to specific value 53 ulong width; 54 55 @setter(150UL) 56 ulong height; 57 58 @setter(500UL) 59 ulong length; 60 } 61 62 /** 63 A class representing a car. 64 **/ 65 @component 66 class Car { 67 68 private { 69 Color color_; // Car color 70 Size size_; // Car size 71 } 72 73 public { 74 75 @constructor(lref!Size) // Construct component using Size component from IoC container. 76 this(Size size) { 77 this.size_ = size; 78 } 79 80 @property { 81 82 @autowired // Autowire property with a component from IoC container 83 Car color(Color color) @safe nothrow { 84 this.color_ = color; 85 86 return this; 87 } 88 89 inout(Color) color() @safe nothrow pure inout { 90 return this.color_; 91 } 92 93 inout(Size) size() @safe nothrow pure inout { 94 return this.size_; 95 } 96 } 97 } 98 } 99 100 class Mercedes : Car { 101 this(Size s) { 102 super(s); 103 } 104 } 105 106 class Volkswagen : Car { 107 this(Size s) { 108 super(s); 109 } 110 } 111 112 @component // Configuration component that creates components managed by container. 113 class Manufacturer { 114 115 public { 116 @component // Add component to container that is constructed by Manufacturer. 117 Mercedes makeMercedes() { 118 return new Mercedes(Size(201, 150, 501)); 119 } 120 } 121 } 122 123 void print(Car car) { 124 writeln("You bought a new ", car.classinfo.name, " with following specs:"); 125 writeln("Size:\t", car.size()); 126 writeln("Color:\t", car.color()); 127 } 128 129 void main() { 130 auto container = singleton(); // 1. Create container that will manage a color 131 scope(exit) container.terminate(); // 6. Shutdown the container 132 133 with (container.configure) { 134 135 register!Volkswagen // 2. Register color into container. 136 .construct(Size(100, 200, 500)) 137 .set!"color"("blue".lref); // 3. Bind blue color from container 138 139 register!Color("blue") 140 .set!"r"(cast(ubyte) 0) 141 .set!"g"(cast(ubyte) 0) 142 .set!"b"(cast(ubyte) 255); 143 } 144 145 container.scan!app; // 4. Scan app module, and register all annotated components. 146 147 container.instantiate(); // 5. Start the IoC container. 148 149 container.locate!Car.print; // 5. Use component from IoC container. 150 container.locate!Mercedes.print; 151 container.locate!Volkswagen.print; 152 } 153 ------------------- 154 155 License: 156 Boost Software License - Version 1.0 - August 17th, 2003 157 158 Permission is hereby granted, free of charge, to any person or organization 159 obtaining a copy of the software and accompanying documentation covered by 160 this license (the "Software") to use, reproduce, display, distribute, 161 execute, and transmit the Software, and to prepare derivative works of the 162 Software, and to permit third-parties to whom the Software is furnished to 163 do so, all subject to the following: 164 165 The copyright notices in the Software and this entire statement, including 166 the above license grant, this restriction and the following disclaimer, 167 must be included in all copies of the Software, in whole or in part, and 168 all derivative works of the Software, unless such copies or derivative 169 works are solely in the form of machine-executable object code generated by 170 a source language processor. 171 172 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 173 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 174 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 175 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 176 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 177 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 178 DEALINGS IN THE SOFTWARE. 179 180 Authors: 181 aermicioi 182 ++/ 183 184 module minimal; 185 186 import aermicioi.aedi; 187 import std.stdio; 188 189 /** 190 A struct that should be managed by container. 191 **/ 192 @component 193 struct Color { 194 @setter(cast(ubyte) 255) 195 ubyte r; 196 197 @setter(cast(ubyte) 10) 198 ubyte g; 199 200 @setter(cast(ubyte) 10) 201 ubyte b; 202 } 203 204 /** 205 Size of a car. 206 **/ 207 @component // Register component using annotations 208 struct Size { 209 210 @setter(200UL) // Set property to specific value 211 ulong width; 212 213 @setter(150UL) 214 ulong height; 215 216 @setter(500UL) 217 ulong length; 218 } 219 220 /** 221 A class representing a car. 222 **/ 223 @component 224 class Car { 225 226 private { 227 Color color_; // Car color 228 Size size_; // Car size 229 } 230 231 public { 232 233 @constructor(lref!Size) // Construct component using Size component from IoC container. 234 this(Size size) { 235 this.size_ = size; 236 } 237 238 @property { 239 240 @autowired // Autowire property with a component from IoC container 241 Car color(Color color) @safe nothrow { 242 this.color_ = color; 243 244 return this; 245 } 246 247 inout(Color) color() @safe nothrow pure inout { 248 return this.color_; 249 } 250 251 inout(Size) size() @safe nothrow pure inout { 252 return this.size_; 253 } 254 } 255 } 256 } 257 258 class Mercedes : Car { 259 this(Size s) { 260 super(s); 261 } 262 } 263 264 class Volkswagen : Car { 265 this(Size s) { 266 super(s); 267 } 268 } 269 270 @component // Configuration component that creates components managed by container. 271 class Manufacturer { 272 273 public { 274 @component // Add component to container that is constructed by Manufacturer. 275 Mercedes makeMercedes() { 276 return new Mercedes(Size(201, 150, 501)); 277 } 278 } 279 } 280 281 void print(Car car) { 282 writeln("You bought a new ", car.classinfo.name, " with following specs:"); 283 writeln("Size:\t", car.size()); 284 writeln("Color:\t", car.color()); 285 } 286 287 void main() { 288 auto container = singleton(); // 1. Create container that will manage a color 289 scope(exit) container.terminate(); // 6. Shutdown the container 290 291 with (container.configure) { 292 293 register!Volkswagen // 2. Register color into container. 294 .construct(Size(100, 200, 500)) 295 .set!"color"("blue".lref); // 3. Bind blue color from container 296 297 register!Color("blue") 298 .set!"r"(cast(ubyte) 0) 299 .set!"g"(cast(ubyte) 0) 300 .set!"b"(cast(ubyte) 255); 301 } 302 303 container.scan!minimal; // 4. Scan minimal module, and register all annotated components. 304 305 container.instantiate(); // 5. Start the IoC container. 306 307 container.locate!Car.print; // 5. Use component from IoC container. 308 container.locate!Mercedes.print; 309 container.locate!Volkswagen.print; 310 }