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<X> gives a misleading result in that case.
We need to do the instantiation check within the scope of DependencyFactory
This commit is contained in:
Fischlurch 2018-03-30 06:48:34 +02:00
parent b3d18c1a74
commit 5d0c2b6d2c
3 changed files with 57 additions and 15 deletions

View file

@ -187,9 +187,25 @@ namespace lib {
atDestruction ([obj]{ delete obj; });
return obj;
}
// try to instantiate the default ctor
template<class X, typename = decltype(X())>
static std::true_type __try_instantiate(int);
template<class>
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<typename X>
struct canDefaultConstruct
: decltype(__try_instantiate<X>(0))
{ };
template<class TAR>
static meta::enable_if<std::is_constructible<TAR>,
static meta::enable_if<canDefaultConstruct<TAR>,
TAR* >
buildInstance()
{
@ -204,7 +220,7 @@ namespace lib {
"Application architecture or lifecycle is seriously broken.");
}
template<class ABS>
static meta::disable_if<std::__or_<std::is_abstract<ABS>,std::is_constructible<ABS>>,
static meta::disable_if<std::__or_<std::is_abstract<ABS>,canDefaultConstruct<ABS>>,
ABS* >
buildInstance()
{

View file

@ -332,6 +332,11 @@ namespace test{
return magic_++;
}
};
// NOTE: the following is rejected due to missing default ctor
DependInject<Dummy<9>>::useSingleton<Veryspecial>();
VERIFY_ERROR (FATAL, Depend<Dummy<9>>{}() );
int backdoor = 22;
@ -358,6 +363,11 @@ namespace test{
{////////////////////////////////////////////////////TEST-Scope
////////////// NOTE: the following does not compile
// // since Veryspecial has no default ctor...
// //
// DependInject<Dum>::Local<Dum> impossible;
DependInject<Dum>::Local<Dum> 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());

View file

@ -27697,9 +27697,9 @@
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1522110414912" ID="ID_1861060212" MODIFIED="1522110495402" TEXT="Singleton-Erzeugung zusammenf&#xfc;hren">
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1522110414912" ID="ID_1861060212" MODIFIED="1522384924858" TEXT="Singleton-Erzeugung zusammenf&#xfc;hren">
<linktarget COLOR="#5f8d94" DESTINATION="ID_1861060212" ENDARROW="Default" ENDINCLINATION="-566;0;" ID="Arrow_ID_319700222" SOURCE="ID_1624172022" STARTARROW="None" STARTINCLINATION="205;-440;"/>
<icon BUILTIN="flag-yellow"/>
<icon BUILTIN="pencil"/>
<node CREATED="1522110563499" ID="ID_470760423" MODIFIED="1522113397796" TEXT="stets ausf&#xfc;hrend">
<icon BUILTIN="idea"/>
<node CREATED="1522110568307" ID="ID_311971109" MODIFIED="1522110579069" TEXT="Depend&lt;SUB&gt;"/>
@ -27772,8 +27772,8 @@
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1522200092935" ID="ID_1314237888" MODIFIED="1522382097329" TEXT="Deleter-Behandlung">
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1522200092935" ID="ID_1314237888" MODIFIED="1522384929202" TEXT="Deleter-Behandlung">
<icon BUILTIN="button_ok"/>
<node CREATED="1522200102534" ID="ID_284894079" MODIFIED="1522200105025" TEXT="bisher">
<node CREATED="1522200106373" ID="ID_1981188993" MODIFIED="1522200226028" TEXT="was die Factory zur&#xfc;ckliefert, wird nicht gemanaged">
<icon BUILTIN="broken-line"/>
@ -27796,30 +27796,46 @@
<node COLOR="#338800" CREATED="1522200189706" ID="ID_302642427" MODIFIED="1522382084962" TEXT="m&#xf6;glichst alle instance-Pointer zur&#xfc;cksetzen">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1522384942847" ID="ID_1152640572" MODIFIED="1522385141698" TEXT="Fehlermeldung beim Zugriff nach Zerst&#xf6;rung">
<linktarget COLOR="#639d9e" DESTINATION="ID_1152640572" ENDARROW="Default" ENDINCLINATION="-89;0;" ID="Arrow_ID_1512382393" SOURCE="ID_1741501987" STARTARROW="None" STARTINCLINATION="28;-1;"/>
<icon BUILTIN="flag-yellow"/>
</node>
<node COLOR="#338800" CREATED="1522200249626" ID="ID_215336836" MODIFIED="1522382087401" TEXT="Freunschafts-f&#xe4;hig">
<icon BUILTIN="button_ok"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1522384902500" ID="ID_1741501987" MODIFIED="1522385141698" TEXT="Zugriff beim Herunterfahren">
<arrowlink COLOR="#639d9e" DESTINATION="ID_1152640572" ENDARROW="Default" ENDINCLINATION="-89;0;" ID="Arrow_ID_1512382393" STARTARROW="None" STARTINCLINATION="28;-1;"/>
<icon BUILTIN="flag-pink"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1522334796724" ID="ID_1080992734" MODIFIED="1522382015413" TEXT="Funktoren zusammenf&#xfc;hren">
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1522334843062" ID="ID_1526236017" MODIFIED="1522382043115" TEXT="DependencyFactory f&#xfc;r">
</node>
<node COLOR="#338800" CREATED="1522334796724" ID="ID_1080992734" MODIFIED="1522384890030" TEXT="Funktoren zusammenf&#xfc;hren">
<icon BUILTIN="button_ok"/>
<node CREATED="1522334805635" ID="ID_315782435" MODIFIED="1522334817813" TEXT="Erzeugungs-Funktor"/>
<node COLOR="#338800" CREATED="1522334843062" FOLDED="true" ID="ID_1526236017" MODIFIED="1522385032004" TEXT="DependencyFactory f&#xfc;r">
<icon BUILTIN="button_ok"/>
<node CREATED="1522334805635" ID="ID_315782435" MODIFIED="1522384992864" TEXT="Erzeugungs-Funktor"/>
<node CREATED="1522334818473" ID="ID_750129060" MODIFIED="1522334821036" TEXT="Deleter"/>
<node CREATED="1522334822001" ID="ID_644059909" MODIFIED="1522334935421" TEXT="automatisches Instanz-Management"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1522334859291" ID="ID_1496044958" MODIFIED="1522382005045" TEXT="korrekt handhaben">
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1522334859291" ID="ID_1496044958" MODIFIED="1522384876245" TEXT="korrekt handhaben">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1522334896942" ID="ID_1215786079" MODIFIED="1522382047552" TEXT="default-Fall">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1522334903741" ID="ID_1875541619" MODIFIED="1522382049855" TEXT="abstrakte Basisklasse">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1522381984647" ID="ID_136231234" MODIFIED="1522382051295" TEXT="Klasse ohne Default-ctor">
<icon BUILTIN="flag-pink"/>
<node COLOR="#338800" CREATED="1522381984647" ID="ID_136231234" MODIFIED="1522384873920" TEXT="Klasse ohne Default-ctor">
<icon BUILTIN="button_ok"/>
<node CREATED="1522384796267" ID="ID_1913154173" MODIFIED="1522384811849" TEXT="Problem">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1522384813129" ID="ID_502713353" MODIFIED="1522384821715" TEXT="private mit Freunschaft"/>
<node CREATED="1522384822583" ID="ID_1870041254" MODIFIED="1522384845999" TEXT="std::is_constructible&lt;X&gt; kann das nicht unterscheiden"/>
</node>
<node COLOR="#338800" CREATED="1522384848011" ID="ID_834547191" MODIFIED="1522384870993" TEXT="L&#xf6;sung: duck-Detector im Rumpf von DependencyFactory">
<icon BUILTIN="button_ok"/>
</node>
</node>
<node COLOR="#338800" CREATED="1522334912412" ID="ID_1391948557" MODIFIED="1522382053286" TEXT="custom-Funktor">
<icon BUILTIN="button_ok"/>