DI: draft syntax for special dependency injection configuration
This commit is contained in:
parent
eebe31aa7e
commit
e1ca9f447b
3 changed files with 58 additions and 14 deletions
|
|
@ -71,7 +71,7 @@ using lib::ClassLock;
|
|||
using lib::meta::enable_if;
|
||||
|
||||
|
||||
|
||||
namespace {
|
||||
template<typename TAR, typename SEL =void>
|
||||
class InstanceHolder
|
||||
: boost::noncopyable
|
||||
|
|
@ -106,6 +106,7 @@ using lib::meta::enable_if;
|
|||
"Application architecture or lifecycle is seriously broken.");
|
||||
}
|
||||
};
|
||||
}//(End)Implementation helper
|
||||
|
||||
|
||||
|
||||
|
|
@ -171,6 +172,43 @@ template<class SRV>
|
|||
InstanceHolder<SRV> Depend<SRV>::singleton;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////Configuration
|
||||
|
||||
template<class SRV>
|
||||
class DependInject
|
||||
{
|
||||
public:
|
||||
|
||||
template<class SUB>
|
||||
void
|
||||
useSingleton()
|
||||
{
|
||||
UNIMPLEMENTED ("reconfigure to plant a singleton of subclass type");
|
||||
}
|
||||
|
||||
template<class IMP>
|
||||
class ServiceInstance
|
||||
{
|
||||
public:
|
||||
ServiceInstance()
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
template<class IMP>
|
||||
class Local
|
||||
{
|
||||
public:
|
||||
Local()
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////Usage
|
||||
|
||||
struct Dum
|
||||
: boost::noncopyable
|
||||
|
|
|
|||
|
|
@ -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="201803170228" tags="def Concepts draft" changecount="7">
|
||||
<div title="DependencyFactory" creator="Ichthyostega" modifier="Ichthyostega" created="201803110155" modified="201803172347" tags="def Concepts draft" changecount="8">
|
||||
<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.
|
||||
|
||||
|
|
@ -1946,22 +1946,22 @@ The DependencyFactory and thus the behaviour of dependency injection can be reco
|
|||
Deliberately, we do not enforce global consistency statically (since that would lead to one central static configuration). However, a runtime sanity check is performed to ensure configuration actually happens prior to any use, which means any invocation to retrieve (and thus lazily create) the service instance. The following flavours can be configured
|
||||
;default
|
||||
:a singleton instance of the designated type is created lazily, on first access
|
||||
:define an instance for access (preferably static) {{{Depend<Bla> theBla;}}}
|
||||
:define an instance for access (preferably static) {{{Depend<Blah> theBla;}}}
|
||||
:access the singleton instance as {{{theBla().doIt();}}}
|
||||
;singleton subclass
|
||||
:{{{DependInject<Bla> = Singleton<SubBla>}}}
|
||||
:{{{DependInject<Blah>::useSingleton<SubBlah>() }}}
|
||||
:causes the dependency factory {{{Depend<Bla>}}} to create a {{{SubBla}}} singleton instance
|
||||
;attach to service
|
||||
:{{{DependInject<Bla>{ServiceInstance<SubBla>} }}}
|
||||
:* build and manage an instance of {{{SubBla}}} in heap memory immediately (not lazily)
|
||||
:{{{DependInject<Blah>::ServiceInstance<SubBlah> service{p1, p2, p3}}}}
|
||||
:* build and manage an instance of {{{SubBlah}}} in heap memory immediately (not lazily)
|
||||
:* configure the dependency factory to return a reference //to this instance//
|
||||
:* the {{{DependInject<Bla>}}} instance itself acts as lifecycle handle (and managing smart-ptr)
|
||||
:* the generated {{{ServiceInstance<SubBlah>}}} object itself acts as lifecycle handle (and managing smart-ptr)
|
||||
:* when it is destroyed, the dependency factory is automatically cleared, and further access will trigger an error
|
||||
;support for test mocking
|
||||
:{{{DependInject<Bla> mock{Local<SubBla>} }}}
|
||||
:{{{DependInject<Blah>::Local<SubBlah> mock }}}
|
||||
:temporarily shadows whatever configuration resides within the dependency factory
|
||||
:the next access will create a (non singleton) {{{SubBla}}} instance in heap memory and return a {{{Bla&}}}
|
||||
:the {{{DependInject<Bla>}}} again acts as lifecycle handle and smart-ptr to access the {{{SubBla}}} instance like {{{mock->doItSpecial()}}}
|
||||
:the next access will create a (non singleton) {{{SubBlah}}} instance in heap memory and return a {{{Blah&}}}
|
||||
:the generated object again acts as lifecycle handle and smart-ptr to access the {{{SubBlah}}} instance like {{{mock->doItSpecial()}}}
|
||||
:when this handle goes out of scope, the original configuration of the dependency factory is restored
|
||||
|
||||
</pre>
|
||||
|
|
|
|||
|
|
@ -26899,7 +26899,8 @@
|
|||
<node CREATED="1521238662196" ID="ID_1029621449" MODIFIED="1521238671488" TEXT="Heap">
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
</node>
|
||||
<node CREATED="1521238665347" ID="ID_1310408215" MODIFIED="1521238668095" TEXT="statisch">
|
||||
<node CREATED="1521238665347" ID="ID_1310408215" MODIFIED="1521326747660" TEXT="statisch">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1521238747512" ID="ID_183342291" MODIFIED="1521238753603" TEXT="bietet sich an..."/>
|
||||
<node CREATED="1521238754287" ID="ID_1930878495" MODIFIED="1521238758794" TEXT="paßt zum Design-Stil"/>
|
||||
</node>
|
||||
|
|
@ -26993,8 +26994,8 @@
|
|||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1521169130251" ID="ID_1252056818" MODIFIED="1521169146081" TEXT="Zugang für DependInject">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1521324229082" ID="ID_1398878858" MODIFIED="1521324233702" TEXT="Storage">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1521324229082" ID="ID_1398878858" MODIFIED="1521326553373" TEXT="Storage">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1521324240124" ID="ID_1099103129" MODIFIED="1521324253936">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
|
@ -27032,7 +27033,12 @@
|
|||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1521324883035" ID="ID_1438637057" MODIFIED="1521324896069" TEXT="Heap-Allokation könnte insgesamt einfacher sein"/>
|
||||
<node COLOR="#338800" CREATED="1521324883035" ID="ID_1438637057" MODIFIED="1521326539612" TEXT="Heap-Allokation könnte insgesamt einfacher sein">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1521326541575" ID="ID_966508253" MODIFIED="1521326547454" TEXT="umgebaut auf Heap">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1521254014422" ID="ID_961824675" MODIFIED="1521324200616" TEXT="Meyers Singleton oder explizit ausprogrammieren?">
|
||||
<icon BUILTIN="help"/>
|
||||
|
|
|
|||
Loading…
Reference in a new issue