1 /** 2 * This module contains facilities to support value injection. Actual injection is done by the 3 * autowiring mechanism. 4 * 5 * Authors: 6 * Mike Bierlee, m.bierlee@lostmoment.com 7 * Copyright: 2014-2022 Mike Bierlee 8 * License: 9 * This software is licensed under the terms of the MIT license. 10 * The full terms of the license can be found in the LICENSE file. 11 */ 12 module poodinis.valueinjection; 13 14 import poodinis.polyfill : basicExceptionCtors; 15 16 import std.string : format; 17 18 /** 19 * Thrown when something goes wrong during value injection. 20 */ 21 class ValueInjectionException : Exception 22 { 23 mixin basicExceptionCtors; 24 } 25 26 /** 27 * Thrown by injectors when the value with the given key cannot be found. 28 */ 29 class ValueNotAvailableException : Exception 30 { 31 this(string key) 32 { 33 super(format("Value for key %s is not available", key)); 34 } 35 36 this(string key, Throwable cause) 37 { 38 super(format("Value for key %s is not available", key), cause); 39 } 40 } 41 42 /** 43 * UDA used for marking class members which should be value-injected. 44 * 45 * A key must be supplied, which can be in any format depending on how 46 * a value injector reads it. 47 * 48 * When the injector throws a ValueNotAvailableException, the value is 49 * not injected and will keep its original assignment. 50 * 51 * Examples: 52 * --- 53 * class MyClass { 54 * @Value("general.importantNumber") 55 * private int number = 8; 56 * } 57 * --- 58 */ 59 struct Value 60 { 61 /** 62 * The textual key used to find the value by injectors. 63 * 64 * The format is injector-specific. 65 */ 66 string key; 67 } 68 69 /** 70 * UDA used for marking class members which should be value-injected. 71 * 72 * When the injector throws a ValueNotAvailableException, it is re-thrown 73 * instead of being suppressed. 74 * 75 * A key must be supplied, which can be in any format depending on how 76 * a value injector reads it. 77 * 78 * Examples: 79 * --- 80 * class MyClass { 81 * @MandatoryValue("general.valueWhichShouldBeThere") 82 * private int number; 83 * } 84 * --- 85 */ 86 struct MandatoryValue 87 { 88 /** 89 * The textual key used to find the value by injectors. 90 * 91 * The format is injector-specific. 92 */ 93 string key; 94 } 95 96 /** 97 * Interface which should be implemented by value injectors. 98 * 99 * Each value injector injects one specific type. The type can be any primitive 100 * type or that of a struct. While class types are also supported, value injectors 101 * are not intended for them. 102 * 103 * Note that value injectors are also autowired before being used. Values within dependencies of 104 * a value injector are not injected. Neither are values within the value injector itself. 105 * 106 * Value injection is not supported for constructor injection. 107 * 108 * Examples: 109 * --- 110 * class MyIntInjector : ValueInjector!int { 111 * public override int get(string key) { ... } 112 * } 113 * 114 * // In order to make the container use your injector, register it by interface: 115 * container.register!(ValueInjector!int, MyIntInjector); 116 * --- 117 */ 118 interface ValueInjector(Type) 119 { 120 /** 121 * Get a value from the injector by key. 122 * 123 * The key can have any format. Generally you are encouraged 124 * to accept a dot separated path, for example: server.http.port 125 * 126 * Throws: ValueNotAvailableException when the value for the given key is not available for any reason 127 */ 128 Type get(string key); 129 }