From 4c25b91c63276b8223471487519c0348518b4ed7 Mon Sep 17 00:00:00 2001 From: Mike Bierlee Date: Sun, 13 Aug 2017 17:49:40 +0200 Subject: [PATCH] Import modules of argument types of registration type's template before calling post-constructor --- CHANGES.md | 3 +++ source/poodinis/container.d | 16 +++++++++++++++- test/poodinis/valueinjectiontest.d | 29 +++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index caa7293..8c5c68e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,8 @@ Poodinis Changelog ================== +**Unreleased** +* FIX value injectors failing to resolve in certain situations when they inject structs + **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 @PostConstruct UDA for marking methods which should be called after a dependency is resolved and autowired. diff --git a/source/poodinis/container.d b/source/poodinis/container.d index 6c58f4b..11e7ca6 100644 --- a/source/poodinis/container.d +++ b/source/poodinis/container.d @@ -391,7 +391,8 @@ synchronized class DependencyContainer { private void callPostConstructors(Type)(Type instance) { foreach (memberName; __traits(allMembers, Type)) { - mixin(`import ` ~ moduleName!Type ~ `;`); + mixin(createImportsString!Type); + static if (__traits(compiles, __traits(getProtection, __traits(getMember, instance, memberName))) && __traits(getProtection, __traits(getMember, instance, memberName)) == "public" && 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. */ diff --git a/test/poodinis/valueinjectiontest.d b/test/poodinis/valueinjectiontest.d index a85a12e..fbb8e4d 100644 --- a/test/poodinis/valueinjectiontest.d +++ b/test/poodinis/valueinjectiontest.d @@ -12,6 +12,22 @@ import std.exception; 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 unittest { auto container = new shared DependencyContainer(); @@ -105,4 +121,17 @@ version(unittest) { 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); + } }