Add mandatory injection of values

This commit is contained in:
Mike Bierlee 2016-12-11 01:31:09 +01:00
parent 52dcecef9a
commit 86fb525066
3 changed files with 68 additions and 0 deletions

View file

@ -135,6 +135,9 @@ private void autowireMember(string member, size_t memberIndex, Type)(shared(Depe
} else static if (is(typeof(attribute) == Value)) { } else static if (is(typeof(attribute) == Value)) {
enum key = attribute.key; enum key = attribute.key;
injectValue!(member, memberIndex, key, false)(container, instance); injectValue!(member, memberIndex, key, false)(container, instance);
} else static if (is(typeof(attribute) == MandatoryValue)) {
enum key = attribute.key;
injectValue!(member, memberIndex, key, true)(container, instance);
} }
} }
} }

View file

@ -60,6 +60,32 @@ struct Value {
string key; string key;
} }
/**
* UDA used for marking class members which should be value-injected.
*
* When the injector throws a ValueNotAvailableException, it is re-thrown
* instead of being suppressed.
*
* A key must be supplied, which can be in any format depending on how
* a value injector reads it.
*
* Examples:
* ---
* class MyClass {
* @MandatoryValue("general.valueWhichShouldBeThere")
* private int number;
* }
* ---
*/
struct MandatoryValue {
/**
* The textual key used to find the value by injectors.
*
* The format is injector-specific.
*/
string key;
}
/** /**
* Interface which should be implemented by value injectors. * Interface which should be implemented by value injectors.
* *

View file

@ -30,6 +30,11 @@ version(unittest) {
int noms = 9; int noms = 9;
} }
class ConfigWithMandatory {
@MandatoryValue("conf.mustbethere")
int nums;
}
// Test injection of values // Test injection of values
unittest { unittest {
auto container = new shared DependencyContainer(); auto container = new shared DependencyContainer();
@ -91,4 +96,38 @@ version(unittest) {
auto instance = container.resolve!ConfigWithDefaults; auto instance = container.resolve!ConfigWithDefaults;
assert(instance.noms == 9); assert(instance.noms == 9);
} }
// Test mandatory injection of values which are available
unittest {
auto container = new shared DependencyContainer();
container.register!ConfigWithMandatory;
class IntInjector : ValueInjector!int {
public override int get(string key) {
return 7466;
}
}
container.register!(ValueInjector!int, IntInjector);
auto instance = container.resolve!ConfigWithMandatory;
assert(instance.nums == 7466);
}
// Test mandatory injection of values which are not available
unittest {
auto container = new shared DependencyContainer();
container.register!ConfigWithMandatory;
class IntInjector : ValueInjector!int {
public override int get(string key) {
throw new ValueNotAvailableException(key);
}
}
container.register!(ValueInjector!int, IntInjector);
assertThrown!ResolveException(container.resolve!ConfigWithMandatory);
assertThrown!ValueInjectionException(autowire(container, new ConfigWithMandatory()));
}
} }