1 /** 2 Provides an interface for registering components into containers. 3 4 License: 5 Boost Software License - Version 1.0 - August 17th, 2003 6 7 Permission is hereby granted, free of charge, to any person or organization 8 obtaining a copy of the software and accompanying documentation covered by 9 this license (the "Software") to use, reproduce, display, distribute, 10 execute, and transmit the Software, and to prepare derivative works of the 11 Software, and to permit third-parties to whom the Software is furnished to 12 do so, all subject to the following: 13 14 The copyright notices in the Software and this entire statement, including 15 the above license grant, this restriction and the following disclaimer, 16 must be included in all copies of the Software, in whole or in part, and 17 all derivative works of the Software, unless such copies or derivative 18 works are solely in the form of machine-executable object code generated by 19 a source language processor. 20 21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 24 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 25 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 26 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 27 DEALINGS IN THE SOFTWARE. 28 29 Authors: 30 aermicioi 31 **/ 32 module aermicioi.aedi.configurer.register.register; 33 34 import aermicioi.aedi.configurer.register.configuration_context_factory; 35 import aermicioi.aedi.storage.storage; 36 import aermicioi.aedi.storage.locator; 37 import aermicioi.aedi.factory; 38 import aermicioi.aedi.factory.generic_factory; 39 import aermicioi.aedi.factory.wrapping_factory : WrappingFactory; 40 import aermicioi.aedi.factory.proxy_factory; 41 import aermicioi.aedi.container.proxy_container; 42 import aermicioi.aedi.container.container; 43 import aermicioi.util.traits : isReferenceType; 44 import aermicioi.aedi.exception; 45 46 /** 47 Register a new factory for type T object into storage/DI container by id. 48 49 Params: 50 Type = the type of object registered in storage 51 storage = the storage where factory will be stored. 52 locator = the locator that will be used by GenericFactory implementation to fetch required objects. 53 id = the identity by which to register the factory in storage. 54 55 Returns: 56 GenericFactory implementation for further configuration. 57 **/ 58 auto register(Type)(Storage!(ObjectFactory, string) storage, Locator!(Object, string) locator, string id) { 59 auto fact = new GenericFactoryImpl!Type(locator); 60 auto configurable = new ConfigurationContextFactory!Type(); 61 configurable.storage = storage; 62 configurable.locator = locator; 63 configurable.identity = id; 64 configurable.decorated = fact; 65 configurable.wrapper = new WrappingFactory!(Factory!Type)(fact); 66 67 storage.set(configurable.wrapper, id); 68 69 return configurable; 70 } 71 72 /** 73 ditto 74 **/ 75 auto register(Type)(ConfigurableContainer storage, string id) { 76 return register!Type(storage, storage, id); 77 } 78 79 /** 80 Register a new factory for type Type object into storage/DI container by it's fully qualified name. 81 82 Params: 83 Type = the type of object registered in storage 84 storage = the storage where factory will be stored. 85 locator = the locator that will be used by GenericFactory implementation to fetch required objects. 86 87 Returns: 88 GenericFactory implementation for further configuration. 89 **/ 90 auto register(Type)(Storage!(ObjectFactory, string) storage, Locator!(Object, string) locator) { 91 return storage.register!(Type)(locator, name!Type); 92 } 93 94 /** 95 ditto 96 **/ 97 auto register(Type)(ConfigurableContainer storage) { 98 return register!Type(storage, storage); 99 } 100 101 /** 102 Register a new factory for type T object into storage/DI container by Interface fully qualified name. 103 104 Params: 105 Type = the type of object registered in storage 106 Interface = interface implemented by object registered in storage 107 storage = the storage where factory will be stored. 108 locator = the locator that will be used by GenericFactory implementation to fetch required objects. 109 110 Returns: 111 GenericFactory implementation for further configuration. 112 **/ 113 auto register(Interface, Type)(Storage!(ObjectFactory, string) storage, Locator!(Object, string) locator) 114 if (is(Type : Interface) && isReferenceType!Type) { 115 116 return storage.register!Type(locator, name!Interface); 117 } 118 119 /** 120 ditto 121 **/ 122 auto register(Interface, Type)(ConfigurableContainer storage) { 123 return register!(Interface, Type)(storage, storage); 124 } 125 126 /** 127 Register an object into a storage by storageId located in storageLocator. 128 129 Params: 130 Type = the type of object registered in storage 131 storageLocator = locator containing the storage where to store object. 132 locator = locator used to fetch dependencies for registered object 133 id = the id of object registered in storage 134 storageId = the id of storage where object is stored. 135 136 Throws: 137 NotFoundException when storage with storageId is not found. 138 139 Returns: 140 storageLocator for further configuration 141 **/ 142 auto register(Type, R : Locator!())(R storageLocator, Locator!() locator, string id, string storageId = "singleton") 143 if (!is(R : Storage!(ObjectFactory, string))) { 144 import std.algorithm; 145 146 return storageLocator 147 .locate!(Storage!(ObjectFactory, string))(storageId) 148 .register!Type(locator, id); 149 } 150 151 /** 152 ditto 153 **/ 154 auto registerInto(Type, R : Locator!())(R storageLocator, Locator!() locator, string storageId = "singleton") 155 if (!is(R : Storage!(ObjectFactory, string))) { 156 157 return storageLocator.register!Type(locator, name!Type, storageId); 158 } 159 160 /** 161 ditto 162 **/ 163 auto register(Type, R : Locator!())(R locator, string id, string storageId = "singleton") 164 if (!is(R : Storage!(ObjectFactory, string))) { 165 166 return locator.register!Type(locator, id, storageId); 167 } 168 169 /** 170 ditto 171 **/ 172 auto registerInto(Type, R : Locator!())(R locator, string storageId = "singleton") 173 if (!is(R : Storage!(ObjectFactory, string))) { 174 175 return locator.registerInto!Type(locator, storageId); 176 } 177 178 /** 179 Register an object into a storage by storageId located in storageLocator with id being FQN of an Interface that object implements. 180 181 Params: 182 Interface = interface that object implements 183 Type = the type of object registered in storage 184 storageLocator = locator containing the storage where to store object. 185 locator = locator used to fetch dependencies for registered object 186 storageId = the id of storage where object is stored. 187 188 Throws: 189 NotFoundException when storage with storageId is not found. 190 191 Returns: 192 storageLocator for further configuration 193 **/ 194 auto register(Interface, Type, R : Locator!())(R storageLocator, Locator!() locator, string storageId = "singleton") 195 if (!is(R : Storage!(ObjectFactory, string))) { 196 197 return storageLocator.register!Type(locator, name!Interface, storageId); 198 } 199 200 /** 201 ditto 202 **/ 203 auto register(Interface, Type, R : Locator!())(R locator, string storageId = "singleton") 204 if (!is(R : Storage!(ObjectFactory, string))) { 205 206 return locator.register!Type(locator, name!Interface, storageId); 207 } 208 209 /** 210 Register data into an object storage. 211 212 Wraps up any already instantiated data that is not reference type into an object, and saves it into storage. 213 Any data that is of reference type is just saved in storage 214 215 Params: 216 Type = the type of object registered in storage 217 storage = the storage were data is saved 218 data = actual data to be saved 219 id = the identity of data that is to be saved. 220 221 Returns: 222 the storage were data was saved. 223 **/ 224 auto register(Type)(Storage!(Object, string) storage, Type data, string id) { 225 import aermicioi.aedi.storage.wrapper : WrapperImpl; 226 227 static if (is(Type : Object)) { 228 229 storage.set(data, id); 230 } else { 231 232 auto wrapper = new WrapperImpl!Type(data); 233 storage.set(wrapper, id); 234 } 235 236 return storage; 237 } 238 239 /** 240 Register data inta a object storage identified by it's type. 241 242 Wraps up any copy-by-value data into an object, and saves it into storage by it's type. 243 244 Params: 245 Type = the type of object registered in storage 246 storage = the storage were data is saved 247 data = actual data to be saved 248 249 Returns: 250 the storage were data was saved. 251 **/ 252 auto register(Type)(Storage!(Object, string) storage, Type data) { 253 return storage.register!Type(data, name!Type); 254 } 255 256 /** 257 Register data into an object storage identified by implemented interface. 258 259 Wraps up any copy-by-value data into an object, and saves it into storage by it's type. 260 261 Params: 262 Interface = interface that object implements 263 Type = the type of object registered in storage 264 storage = the storage were data is saved 265 data = actual data to be saved 266 267 Returns: 268 the storage were data was saved. 269 **/ 270 auto register(Interface, Type)(Storage!(Object, string) storage, Type data) 271 if (is(Type : Interface) && !is(Type == Interface)) { 272 273 return storage.register!Type(data, name!Interface); 274 } 275 276 /** 277 Register data into an object storage located in locator by storageId. 278 279 Params: 280 Type = the type of object registered in storage 281 locator = locator containing object storage were data is saved. 282 data = the actual data saved in storage 283 id = the id by which data will be identified 284 storageId = identity of storage in locator 285 **/ 286 auto register(Type, R : Locator!())(R locator, Type data, string id, string storageId = "parameters") 287 if (!is(R : Storage!(Object, string))) { 288 import aermicioi.aedi.storage.wrapper : Wrapper; 289 290 locator 291 .locate!(Storage!(Object, string))(storageId) 292 .register!Type(data, id); 293 294 return locator; 295 } 296 297 /** 298 ditto 299 **/ 300 auto registerInto(Type, R : Locator!())(R locator, Type data, string storageId = "parameters") 301 if (!is(R : Storage!(Object, string))) { 302 303 return locator.register!Type(data, name!Type, storageId); 304 } 305 306 /** 307 ditto 308 **/ 309 auto register(Interface, Type, R : Locator!())(R storage, Type object, string storageId = "parameters") 310 if (is(Type : Interface) && !is(R : Storage!(Object, string)) && !is(Type == Interface)) { 311 return storage.register!Type(object, name!Interface, storageId); 312 }