From e1ca9f447b65168ce81b619b0cdb9ba96dad9987 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 18 Mar 2018 00:57:25 +0100 Subject: [PATCH] DI: draft syntax for special dependency injection configuration --- research/try.cpp | 40 +++++++++++++++++++++++++++++++++++++++- wiki/renderengine.html | 18 +++++++++--------- wiki/thinkPad.ichthyo.mm | 14 ++++++++++---- 3 files changed, 58 insertions(+), 14 deletions(-) diff --git a/research/try.cpp b/research/try.cpp index 20d32aa1d..59c87e721 100644 --- a/research/try.cpp +++ b/research/try.cpp @@ -71,7 +71,7 @@ using lib::ClassLock; using lib::meta::enable_if; - +namespace { template 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 InstanceHolder Depend::singleton; +///////////////////////////////////////////////////////Configuration + +template +class DependInject + { + public: + + template + void + useSingleton() + { + UNIMPLEMENTED ("reconfigure to plant a singleton of subclass type"); + } + + template + class ServiceInstance + { + public: + ServiceInstance() + { + + } + }; + + template + class Local + { + public: + Local() + { + + } + }; + }; + + +///////////////////////////////////////////////////////Usage struct Dum : boost::noncopyable diff --git a/wiki/renderengine.html b/wiki/renderengine.html index ce4fee82f..71f34438c 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -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//  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. → [[implementing defaults|DefaultsImplementation]] -
+
//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
 
 
diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 168ce5fcd..5bf514860 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -26899,7 +26899,8 @@ - + + @@ -26993,8 +26994,8 @@ - - + + @@ -27032,7 +27033,12 @@ - + + + + + +