DI: draft configuration for using a subclass Singleton
This commit is contained in:
parent
e1ca9f447b
commit
9f93154f62
3 changed files with 61 additions and 18 deletions
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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//&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.
|
||||
&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 "Singleton" without everyone yelling out "Evil! Evil!" -- 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<Blah>::useSingleton<SubBlah>() }}}
|
||||
:causes the dependency factory {{{Depend<Bla>}}} to create a {{{SubBla}}} singleton instance
|
||||
:causes the dependency factory {{{Depend<Bla>}}} to create a {{{SubBla}}} singleton instance from now on
|
||||
;attach to service
|
||||
:{{{DependInject<Blah>::ServiceInstance<SubBlah> service{p1, p2, p3}}}}
|
||||
:* build and manage an instance of {{{SubBlah}}} in heap memory immediately (not lazily)
|
||||
|
|
|
|||
|
|
@ -26783,19 +26783,27 @@
|
|||
<node CREATED="1521161117092" ID="ID_672223000" MODIFIED="1521161119935" TEXT="Syntax">
|
||||
<node CREATED="1521161120859" ID="ID_1236102866" MODIFIED="1521161279265" TEXT="Depend<Bla> instance"/>
|
||||
<node CREATED="1521161130050" ID="ID_1706757665" MODIFIED="1521161170232" TEXT="instance().doIt()"/>
|
||||
<node CREATED="1521161171324" ID="ID_744864215" MODIFIED="1521161285976" TEXT="DependInject<Bla> = Singleton<UnterBla>"/>
|
||||
<node CREATED="1521161572133" ID="ID_1327949928" MODIFIED="1521213240214" TEXT="DependInject<Bla>{ServiceInstance<UnterBla>}"/>
|
||||
<node CREATED="1521161634205" ID="ID_619508229" MODIFIED="1521161843291" TEXT="DependInject<Bla> mock{Local<UnterBla>}"/>
|
||||
<node CREATED="1521161171324" ID="ID_744864215" MODIFIED="1521330199058" TEXT="DependInject<Bla>::useSingleton<UnterBla>"/>
|
||||
<node CREATED="1521161572133" ID="ID_1327949928" MODIFIED="1521330165247" TEXT="DependInject<Bla>::ServiceInstance<UnterBla> service{p1, p2, p3}"/>
|
||||
<node CREATED="1521161634205" ID="ID_619508229" MODIFIED="1521330190739" TEXT="DependInject<Bla>::Local<UnterBla> mock"/>
|
||||
<node CREATED="1521161919893" ID="ID_1606842354" MODIFIED="1521161929704" TEXT="mock->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 über konkreten Ctor"/>
|
||||
<node CREATED="1521209708336" ID="ID_1667188609" MODIFIED="1521209724265" TEXT="Storage für UnterBla-Instanz bereitstellen"/>
|
||||
<node CREATED="1521208380663" ID="ID_1434723425" MODIFIED="1521210156302" TEXT="neuen lazy-init-Service-Zugang in Depend<Bla> 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ü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<Bla> 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ü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"/>
|
||||
|
|
|
|||
Loading…
Reference in a new issue