DI: draft configuration for using a subclass Singleton

This commit is contained in:
Fischlurch 2018-03-18 01:30:51 +01:00
parent e1ca9f447b
commit 9f93154f62
3 changed files with 61 additions and 18 deletions

View file

@ -174,16 +174,44 @@ InstanceHolder<SRV> Depend<SRV>::singleton;
///////////////////////////////////////////////////////Configuration
using std::move;
template<class SRV>
class DependInject
{
using Factory = typename Depend<SRV>::Factory;
public:
static void
installFactory (Factory&& otherFac)
{
ClassLock<SRV> guard;
if (Depend<SRV>::instance)
throw error::Logic("Attempt to reconfigure dependency injection after the fact. "
"The previously installed factory (typically Singleton) was already used."
, error::LUMIERA_ERROR_LIFECYCLE);
Depend<SRV>::factory = move (otherFac);
}
static void
disableFactory()
{
ClassLock<SRV> guard;
Depend<SRV>::factory = Depend<SRV>::disabledFactory;
}
template<class SUB>
void
static void
useSingleton()
{
UNIMPLEMENTED ("reconfigure to plant a singleton of subclass type");
static InstanceHolder<SUB> singleton;
installFactory ([&]()
{
disableFactory();
return singleton.buildInstance();
});
}
template<class IMP>
@ -225,7 +253,7 @@ struct Dummy
: Dum
{
Dummy() { checksum += N; }
~Dummy() { checksum -= N; }
~Dummy() { checksum -= N; cout << "~Dummy<"<<N<<">"<<endl;}
virtual int
probe()
@ -235,6 +263,7 @@ struct Dummy
};
using error::LUMIERA_ERROR_LIFECYCLE;
int
main (int, char**)
@ -254,8 +283,12 @@ main (int, char**)
SHOW_EXPR( checksum );
Depend<Dum> dumm;
// Depend<Dum>::factory = [](){ return nullptr; };
DependInject<Dum>::useSingleton<Dummy<7>>();
SHOW_EXPR( dumm().probe() );
SHOW_EXPR( checksum );
VERIFY_ERROR (LIFECYCLE, DependInject<Dum>::useSingleton<Dummy<9>>() );
SHOW_EXPR( Depend<Dum>{}().probe() );
SHOW_EXPR( checksum );
cout << "\n.gulp.\n";

View file

@ -1927,7 +1927,7 @@ As we don't have a Prolog interpreter on board yet, we utilize a mock store with
{{{default(Obj)}}} is a predicate expressing that the object {{{Obj}}} can be considered the default setup under the given conditions. Using the //default// can be considered as a shortcut for actually finding an exact and unique solution. The latter would require to specify all sorts of detailed properties up to the point where only one single object can satisfy all conditions. On the other hand, leaving some properties unspecified would yield a set of solutions (and the user code issuing the query had to provide means for selecting one solution from this set). Just falling back on the //default// means that the user code actually doesn't care for any additional properties (as long as the properties he //does// care for are satisfied). Nothing is said specifically on //how//&amp;nbsp; this default gets configured; actually there can be rules //somewhere,// and, additionally, anything encountered once while asking for a default can be re-used as default under similar circumstances.
&amp;rarr; [[implementing defaults|DefaultsImplementation]]</pre>
</div>
<div title="DependencyFactory" creator="Ichthyostega" modifier="Ichthyostega" created="201803110155" modified="201803172347" tags="def Concepts draft" changecount="8">
<div title="DependencyFactory" creator="Ichthyostega" modifier="Ichthyostega" created="201803110155" modified="201803180023" tags="def Concepts draft" changecount="9">
<pre>//Access point to dependencies by-name.//
In the Lumiera code base, we refrain from building or using a full-blown Dependency Injection Container. A lot of FUD has been spread regarding Dependency Injection and Singletons, to the point that a majority of developers confuses and conflates the ~Inversion-of-Control principle (which is essential) with the use of a ~DI-Container. Today, you can not even mention the word &quot;Singleton&quot; without everyone yelling out &quot;Evil! Evil!&quot; -- while most of these people just feel comfortable living in the annotation hell.
@ -1950,7 +1950,7 @@ Deliberately, we do not enforce global consistency statically (since that would
:access the singleton instance as {{{theBla().doIt();}}}
;singleton subclass
:{{{DependInject&lt;Blah&gt;::useSingleton&lt;SubBlah&gt;() }}}
:causes the dependency factory {{{Depend&lt;Bla&gt;}}} to create a {{{SubBla}}} singleton instance
:causes the dependency factory {{{Depend&lt;Bla&gt;}}} to create a {{{SubBla}}} singleton instance from now on
;attach to service
:{{{DependInject&lt;Blah&gt;::ServiceInstance&lt;SubBlah&gt; service{p1, p2, p3}}}}
:* build and manage an instance of {{{SubBlah}}} in heap memory immediately (not lazily)

View file

@ -26783,19 +26783,27 @@
<node CREATED="1521161117092" ID="ID_672223000" MODIFIED="1521161119935" TEXT="Syntax">
<node CREATED="1521161120859" ID="ID_1236102866" MODIFIED="1521161279265" TEXT="Depend&lt;Bla&gt; instance"/>
<node CREATED="1521161130050" ID="ID_1706757665" MODIFIED="1521161170232" TEXT="instance().doIt()"/>
<node CREATED="1521161171324" ID="ID_744864215" MODIFIED="1521161285976" TEXT="DependInject&lt;Bla&gt; = Singleton&lt;UnterBla&gt;"/>
<node CREATED="1521161572133" ID="ID_1327949928" MODIFIED="1521213240214" TEXT="DependInject&lt;Bla&gt;{ServiceInstance&lt;UnterBla&gt;}"/>
<node CREATED="1521161634205" ID="ID_619508229" MODIFIED="1521161843291" TEXT="DependInject&lt;Bla&gt; mock{Local&lt;UnterBla&gt;}"/>
<node CREATED="1521161171324" ID="ID_744864215" MODIFIED="1521330199058" TEXT="DependInject&lt;Bla&gt;::useSingleton&lt;UnterBla&gt;"/>
<node CREATED="1521161572133" ID="ID_1327949928" MODIFIED="1521330165247" TEXT="DependInject&lt;Bla&gt;::ServiceInstance&lt;UnterBla&gt; service{p1, p2, p3}"/>
<node CREATED="1521161634205" ID="ID_619508229" MODIFIED="1521330190739" TEXT="DependInject&lt;Bla&gt;::Local&lt;UnterBla&gt; mock"/>
<node CREATED="1521161919893" ID="ID_1606842354" MODIFIED="1521161929704" TEXT="mock-&gt;doItSpecial()"/>
</node>
<node CREATED="1521207954859" ID="ID_631339002" MODIFIED="1521207965947" TEXT="Analyse">
<node CREATED="1521208242178" ID="ID_539882602" MODIFIED="1521208246821" TEXT="erforderliche Mechanismen">
<node CREATED="1521208254376" ID="ID_1933406851" MODIFIED="1521208256603" TEXT="Singleton">
<node CREATED="1521208339124" ID="ID_287433738" MODIFIED="1521209063045" TEXT="Closure &#xfc;ber konkreten Ctor"/>
<node CREATED="1521209708336" ID="ID_1667188609" MODIFIED="1521209724265" TEXT="Storage f&#xfc;r UnterBla-Instanz bereitstellen"/>
<node CREATED="1521208380663" ID="ID_1434723425" MODIFIED="1521210156302" TEXT="neuen lazy-init-Service-Zugang in Depend&lt;Bla&gt; installieren"/>
<node CREATED="1521208395181" ID="ID_1161468794" MODIFIED="1521210186010" TEXT="Check, ob der vorher dort bestehende Zugang bereits verwendet wurde"/>
<node CREATED="1521208451621" ID="ID_1429591553" MODIFIED="1521208472454" TEXT="Exception aus DependInject, falls ja"/>
<node COLOR="#338800" CREATED="1521209708336" ID="ID_1667188609" MODIFIED="1521332921903" TEXT="Storage f&#xfc;r UnterBla-Instanz bereitstellen">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1521208380663" ID="ID_1434723425" MODIFIED="1521332927022" TEXT="neuen lazy-init-Service-Zugang in Depend&lt;Bla&gt; installieren">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1521208395181" ID="ID_1161468794" MODIFIED="1521332931094" TEXT="Check, ob der vorher dort bestehende Zugang bereits verwendet wurde">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1521208451621" ID="ID_1429591553" MODIFIED="1521332932846" TEXT="Exception aus DependInject, falls ja">
<icon BUILTIN="button_ok"/>
</node>
</node>
<node CREATED="1521208257336" ID="ID_1129640741" MODIFIED="1521208261323" TEXT="ServiceInstance">
<node CREATED="1521208859989" ID="ID_549061661" MODIFIED="1521208874756" TEXT="Lazy-Init-Factory deaktivieren"/>
@ -26955,13 +26963,15 @@
<node CREATED="1521169086441" ID="ID_284471203" MODIFIED="1521169088676" TEXT="Design">
<node CREATED="1521240056932" ID="ID_1189728630" MODIFIED="1521240061863" TEXT="Strukturen">
<node CREATED="1521240105285" ID="ID_711335043" MODIFIED="1521240109744" TEXT="Dependency-Factory">
<node CREATED="1521240317600" ID="ID_1626104494" MODIFIED="1521240328410" TEXT="Design-1">
<node CREATED="1521240317600" ID="ID_1626104494" MODIFIED="1521332944744" TEXT="Design-1">
<icon BUILTIN="button_cancel"/>
<node CREATED="1521240110948" ID="ID_219745040" MODIFIED="1521240117087" TEXT="ist ein Interface"/>
<node CREATED="1521240117611" ID="ID_786865088" MODIFIED="1521240124694" TEXT="nicht getemplated"/>
<node CREATED="1521240284429" ID="ID_1132898054" MODIFIED="1521240294807" TEXT="eingebettetes getyptes Trampolin"/>
<node CREATED="1521240298267" ID="ID_116565565" MODIFIED="1521240312364" TEXT="Folge: static_cast nach Factory-Aufruf"/>
</node>
<node CREATED="1521240336717" ID="ID_468626388" MODIFIED="1521240340704" TEXT="Design-2">
<node CREATED="1521240336717" ID="ID_468626388" MODIFIED="1521332949167" TEXT="Design-2">
<icon BUILTIN="button_ok"/>
<node CREATED="1521241524730" ID="ID_267557752" MODIFIED="1521241530652" TEXT="ist generisches Front-End"/>
<node CREATED="1521241625115" ID="ID_469205839" MODIFIED="1521241635214" TEXT="bietet API zum (re)Konfigurieren"/>
<node CREATED="1521241544559" ID="ID_1174783081" MODIFIED="1521241552521" TEXT="nur eine Funktion konfigurierbar">
@ -26985,7 +26995,7 @@
</node>
</node>
<node CREATED="1521240053852" ID="ID_666003564" MODIFIED="1521240074107" TEXT="Detail-Fragen">
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1521169099047" ID="ID_1183392158" MODIFIED="1521169127596" TEXT="DependencyFactory-Basisklasse">
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1521169099047" ID="ID_1183392158" MODIFIED="1521332981466" TEXT="DependencyFactory-Rahmenklasse">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1521169111957" ID="ID_1706232823" MODIFIED="1521169126860" TEXT="Ort f&#xfc;r den Implementierungs-Pointer">
@ -27071,8 +27081,8 @@
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1521253797733" ID="ID_1640990866" MODIFIED="1521253802565" TEXT="Fehlerbehandlung">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1521253803963" ID="ID_100415207" MODIFIED="1521253827633" TEXT="Installation wenn Factory bereits genutzt wurde">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1521253803963" ID="ID_100415207" MODIFIED="1521332991888" TEXT="Installation wenn Factory bereits genutzt wurde">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1521253831776" ID="ID_1332033733" MODIFIED="1521303545433" TEXT="Zugriff auf Service bevor er hochgefahren wurde">
<icon BUILTIN="flag-yellow"/>