From 5d0c2b6d2cd4483e76e077d6f934fb08c1b9887e Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 30 Mar 2018 06:48:34 +0200 Subject: [PATCH] DI: special solution for singletons with private default ctor ...which declare DependencyFactory as friend. Yes, we want to encourrage that usage pattern. Problem is, std::is_constructible gives a misleading result in that case. We need to do the instantiation check within the scope of DependencyFactory --- src/lib/depend2.hpp | 20 +++++++++- .../library/dependency-configuration-test.cpp | 12 +++++- wiki/thinkPad.ichthyo.mm | 40 +++++++++++++------ 3 files changed, 57 insertions(+), 15 deletions(-) diff --git a/src/lib/depend2.hpp b/src/lib/depend2.hpp index 0277b7b54..4fef8ba27 100644 --- a/src/lib/depend2.hpp +++ b/src/lib/depend2.hpp @@ -187,9 +187,25 @@ namespace lib { atDestruction ([obj]{ delete obj; }); return obj; } + + // try to instantiate the default ctor + template + static std::true_type __try_instantiate(int); + template + static std::false_type __try_instantiate(...); + + /** metafunction: can we instantiate the desired object here? + * @remark need to perform the check right here in this scope, because + * default ctor can be private with DependencyFactory declared friend + */ + template + struct canDefaultConstruct + : decltype(__try_instantiate(0)) + { }; + template - static meta::enable_if, + static meta::enable_if, TAR* > buildInstance() { @@ -204,7 +220,7 @@ namespace lib { "Application architecture or lifecycle is seriously broken."); } template - static meta::disable_if,std::is_constructible>, + static meta::disable_if,canDefaultConstruct>, ABS* > buildInstance() { diff --git a/tests/library/dependency-configuration-test.cpp b/tests/library/dependency-configuration-test.cpp index 4bc4991b0..897122626 100644 --- a/tests/library/dependency-configuration-test.cpp +++ b/tests/library/dependency-configuration-test.cpp @@ -332,6 +332,11 @@ namespace test{ return magic_++; } }; + + // NOTE: the following is rejected due to missing default ctor + DependInject>::useSingleton(); + VERIFY_ERROR (FATAL, Depend>{}() ); + int backdoor = 22; @@ -358,6 +363,11 @@ namespace test{ {////////////////////////////////////////////////////TEST-Scope +////////////// NOTE: the following does not compile +// // since Veryspecial has no default ctor... +// // +// DependInject::Local impossible; + DependInject::Local insidious ([&]{ return new Veryspecial{backdoor}; }); CHECK ((1+5+7+9) == checksum ); @@ -378,7 +388,7 @@ namespace test{ CHECK ((1+5+7+9+9) == checksum ); }////////////////////////////////////////////////////(End)TEST-Scope - + CHECK ((1+5+7+9) == checksum ); CHECK ((1+5+7+9)*7 == dumm().probe() ); CHECK ( 0 == tricky().probe()); diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 9501c5a1a..024a8b9d0 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -27697,9 +27697,9 @@ - + - + @@ -27772,8 +27772,8 @@ - - + + @@ -27796,30 +27796,46 @@ + + + + + + + - - - + + - + + + - - + + - - + + + + + + + + + +