mirror of
https://github.com/mbierlee/poodinis.git
synced 2024-11-15 04:04:01 +01:00
Make it clear when a value injector is missing
This commit is contained in:
parent
4954979574
commit
9eb3a89695
|
@ -206,10 +206,14 @@ private QualifierType createOrResolveInstance(MemberType, QualifierType, bool cr
|
||||||
|
|
||||||
private void injectValue(string member, size_t memberIndex, string key, Type)(shared(DependencyContainer) container, Type instance) {
|
private void injectValue(string member, size_t memberIndex, string key, Type)(shared(DependencyContainer) container, Type instance) {
|
||||||
alias MemberType = typeof(Type.tupleof[memberIndex]);
|
alias MemberType = typeof(Type.tupleof[memberIndex]);
|
||||||
auto injector = container.resolve!(ValueInjector!MemberType);
|
try {
|
||||||
instance.tupleof[memberIndex] = injector.get(key);
|
auto injector = container.resolve!(ValueInjector!MemberType);
|
||||||
debug(poodinisVerbose) {
|
instance.tupleof[memberIndex] = injector.get(key);
|
||||||
printDebugValueInjection(typeid(Type), &instance, member, typeid(MemberType), key);
|
debug(poodinisVerbose) {
|
||||||
|
printDebugValueInjection(typeid(Type), &instance, member, typeid(MemberType), key);
|
||||||
|
}
|
||||||
|
} catch (ResolveException e) {
|
||||||
|
throw new ValueInjectionException(format("Could not inject value of type %s into %s.%s: value injector is missing for this type.", typeid(MemberType), typeid(Type), member));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ import poodinis.registration;
|
||||||
import poodinis.autowire;
|
import poodinis.autowire;
|
||||||
import poodinis.context;
|
import poodinis.context;
|
||||||
import poodinis.factory;
|
import poodinis.factory;
|
||||||
|
import poodinis.valueinjection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exception thrown when errors occur while resolving a type in a dependency container.
|
* Exception thrown when errors occur while resolving a type in a dependency container.
|
||||||
|
@ -33,6 +34,10 @@ class ResolveException : Exception {
|
||||||
this(string message, TypeInfo resolveType) {
|
this(string message, TypeInfo resolveType) {
|
||||||
super(format("Exception while resolving type %s: %s", resolveType.toString(), message));
|
super(format("Exception while resolving type %s: %s", resolveType.toString(), message));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this(Throwable cause, TypeInfo resolveType) {
|
||||||
|
super(format("Exception while resolving type %s", resolveType.toString()), cause);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -286,7 +291,12 @@ synchronized class DependencyContainer {
|
||||||
}
|
}
|
||||||
|
|
||||||
Registration registration = getQualifiedRegistration(resolveType, qualifierType, cast(Registration[]) *candidates);
|
Registration registration = getQualifiedRegistration(resolveType, qualifierType, cast(Registration[]) *candidates);
|
||||||
return resolveAutowiredInstance!QualifierType(registration);
|
|
||||||
|
try {
|
||||||
|
return resolveAutowiredInstance!QualifierType(registration);
|
||||||
|
} catch (ValueInjectionException e) {
|
||||||
|
throw new ResolveException(e, resolveType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private QualifierType resolveAutowiredInstance(QualifierType)(Registration registration) {
|
private QualifierType resolveAutowiredInstance(QualifierType)(Registration registration) {
|
||||||
|
|
|
@ -11,23 +11,40 @@
|
||||||
*/
|
*/
|
||||||
module poodinis.valueinjection;
|
module poodinis.valueinjection;
|
||||||
|
|
||||||
|
import std.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thrown when something goes wrong during value injection.
|
||||||
|
*/
|
||||||
|
class ValueInjectionException : Exception {
|
||||||
|
mixin basicExceptionCtors;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UDA used for marking class members which should be value-injected.
|
* UDA used for marking class members which should be value-injected.
|
||||||
*
|
*
|
||||||
* A key must be supplied, which can be in any format depending on how
|
* A key must be supplied, which can be in any format depending on how
|
||||||
* a value injector reads it.
|
* a value injector reads it.
|
||||||
*
|
*
|
||||||
|
* When the injector throws a ValueNotAvailableException, the value is
|
||||||
|
* not injected and will keep its original assignment.
|
||||||
|
*
|
||||||
* Examples:
|
* Examples:
|
||||||
* ---
|
* ---
|
||||||
* class MyClass {
|
* class MyClass {
|
||||||
* @Value("general.importantNumber")
|
* @Value("general.importantNumber")
|
||||||
* private int number;
|
* private int number = 8;
|
||||||
* }
|
* }
|
||||||
* ---
|
* ---
|
||||||
*/
|
*/
|
||||||
struct Value {
|
struct Value {
|
||||||
|
/**
|
||||||
|
* The textual key used to find the value by injectors.
|
||||||
|
*
|
||||||
|
* The format is injector-specific.
|
||||||
|
*/
|
||||||
string key;
|
string key;
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface which should be implemented by value injectors.
|
* Interface which should be implemented by value injectors.
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
|
|
||||||
import poodinis;
|
import poodinis;
|
||||||
|
|
||||||
|
import std.exception;
|
||||||
|
|
||||||
version(unittest) {
|
version(unittest) {
|
||||||
struct Thing {
|
struct Thing {
|
||||||
int x;
|
int x;
|
||||||
|
@ -58,4 +60,13 @@ version(unittest) {
|
||||||
assert(instance.name == "Le Chef");
|
assert(instance.name == "Le Chef");
|
||||||
assert(instance.thing.x == 8899);
|
assert(instance.thing.x == 8899);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test injection of values throws exception when injector is not there
|
||||||
|
unittest {
|
||||||
|
auto container = new shared DependencyContainer();
|
||||||
|
container.register!MyConfig;
|
||||||
|
assertThrown!ResolveException(container.resolve!MyConfig);
|
||||||
|
|
||||||
|
assertThrown!ValueInjectionException(autowire(container, new MyConfig()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue