Import modules of argument types of registration type's template before calling post-constructor

This commit is contained in:
Mike Bierlee 2017-08-13 17:49:40 +02:00
parent 9be2d4fac1
commit 4c25b91c63
3 changed files with 47 additions and 1 deletions

View file

@ -1,5 +1,8 @@
Poodinis Changelog Poodinis Changelog
================== ==================
**Unreleased**
* FIX value injectors failing to resolve in certain situations when they inject structs
**Version 8.0.0** **Version 8.0.0**
* ADD value injection. Members with UDA @Value will be attempted to be injected with a value-type. See tutorial and examples for more info. * ADD value injection. Members with UDA @Value will be attempted to be injected with a value-type. See tutorial and examples for more info.
* ADD @PostConstruct UDA for marking methods which should be called after a dependency is resolved and autowired. * ADD @PostConstruct UDA for marking methods which should be called after a dependency is resolved and autowired.

View file

@ -391,7 +391,8 @@ synchronized class DependencyContainer {
private void callPostConstructors(Type)(Type instance) { private void callPostConstructors(Type)(Type instance) {
foreach (memberName; __traits(allMembers, Type)) { foreach (memberName; __traits(allMembers, Type)) {
mixin(`import ` ~ moduleName!Type ~ `;`); mixin(createImportsString!Type);
static if (__traits(compiles, __traits(getProtection, __traits(getMember, instance, memberName))) static if (__traits(compiles, __traits(getProtection, __traits(getMember, instance, memberName)))
&& __traits(getProtection, __traits(getMember, instance, memberName)) == "public" && __traits(getProtection, __traits(getMember, instance, memberName)) == "public"
&& isFunction!(mixin(fullyQualifiedName!Type ~ `.` ~ memberName)) && isFunction!(mixin(fullyQualifiedName!Type ~ `.` ~ memberName))
@ -401,6 +402,19 @@ synchronized class DependencyContainer {
} }
} }
private static string createImportsString(Type)() {
string imports = `import ` ~ moduleName!Type ~ `;`;
static if (__traits(compiles, TemplateArgsOf!Type)) {
foreach(TemplateArgType; TemplateArgsOf!Type) {
static if (!isBuiltinType!TemplateArgType) {
imports ~= "import " ~ moduleName!TemplateArgType ~ ";";
}
}
}
return imports;
}
/** /**
* Clears all dependency registrations managed by this container. * Clears all dependency registrations managed by this container.
*/ */

View file

@ -12,6 +12,22 @@ import std.exception;
version(unittest) { version(unittest) {
struct LocalStruct {
bool wasInjected = false;
}
class LocalStructInjector : ValueInjector!LocalStruct {
public override LocalStruct get(string key) {
auto data = LocalStruct(true);
return data;
}
}
class LocalClassWithStruct {
@Value("")
public LocalStruct localStruct;
}
// Test injection of values // Test injection of values
unittest { unittest {
auto container = new shared DependencyContainer(); auto container = new shared DependencyContainer();
@ -105,4 +121,17 @@ version(unittest) {
assert(injector.config.noms == 8899); assert(injector.config.noms == 8899);
} }
// Test resolving locally defined struct injector (github issue #20)
unittest {
auto container = new shared DependencyContainer();
container.register!(ValueInjector!LocalStruct, LocalStructInjector);
container.register!LocalClassWithStruct;
auto injector = container.resolve!(ValueInjector!LocalStruct);
assert(injector !is null);
auto localClass = container.resolve!LocalClassWithStruct;
assert(localClass.localStruct.wasInjected);
}
} }