Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
215 lines (167 sloc) 6.73 KB
INJECT
======
Inject is intended to be a C++ dependency injection library which:
* is header-only
Library does not require anything but including its header files
* is non-intrusive
Any class can be a component. No need to inherit library interfaces, declare
mandatory members or include a macro in the class declaration. For a class
to be a component all it needs is to have its default-constructor public and
functioning.
* is macro-less
The library does not rely on pre-processing magic for code-generation. No
need to declare constructors in a special way or include black-magic macros
in your class' body.
* is declarative
This is similar to the non-intrusive bullet. Using a class as a component
is a matter of declaration, which is done separately from the class'
declaration, see below for examples
* doesn't require code-generation
The library relies only on the standard code generation facilities offered
by C++98 through the template mechanism. No additional scripts/executables
need to be run to get injections functionality to the application.
* is very simple to use
* fully supports allocation and instantiation through std::allocator
* supports up to 10 constructor arguments
* can inject to setter methods (two types, see examples)
* does not use RTTI
* has built-in support for lazy-injection (injection upon first usage as
opposed to construction time)
* is fully C++98 complaint
USAGE & DOCUMENTATION
=====================
- start with the quick reference below
- see: examples/README for code examples
- doxygen: http://www.duvdevani.com/itay/projects/inject/doxygen/
QUICK REFERENCE
===============
[All procedural snippets assume ctx is a context instance]
Register a new component (mandatory for everything else)
--------------------------------------------------------
Declarative:
context<>::component<T> comp_decl;
or:
context<>::component<T> comp_decl("component_name");
Procedural:
TBD
Where:
T - typename of component
Register a component as implementing another component
------------------------------------------------------
Declarative:
context<>::component<T>::provides<S> impls_decl;
Procedural:
TBD
Where:
T - typename of implementing component
S - typename of component implemented
Select implementing component to use when component is requested
----------------------------------------------------------------
[implementing component must be declared as such (see above)]
Declarative:
context<>::component<T>::implemented_by<S[, Scope]> impl_decl;
Procedural:
/* bind T as S implementation */
ctx.bind<T, S[, Scope]>();
or
/* bind T as its own implementation */
ctx.bind<T[, Scope]>();
Where:
T - typename of component implemented
S - typename of implementation component
Scope - (optional) implementation scope, one of: scope_none (new instance
every time - default) and scope_singleton (same instance every time)
Request an instance of a component
----------------------------------
Declarative:
context<>::injected<T> p; // inject at construction time
context<>::injected<T> p(lazy); // injected upon first usage
Procedural:
context<>::ptr<T>::type p = ctx.instance<T>();
Where:
T - typename of component to get instance of
Allocate (and deallocate) a component using a custom allocator
--------------------------------------------------------------
Declarative:
context<>::component<T>::allocator< MyAllocator<T> > alloc_decl;
Procedural:
TBD
Where:
T - typename of component to set allocator for
Instantiate a component with a specific constructor
---------------------------------------------------
Declarative:
context<>::component<T>::constructor<A1[, A2 ... A10]> ctor_decl;
Procedural:
TBD
Where:
T - typename of component
A1..A10 - typename of components in constructor declaration
Inject a component to a C++-style setter during component initialization
------------------------------------------------------------------------
Declarative:
context<>::component<T>::assign_setter<S, &T::setter> setter_decl;
Procedural:
TBD
Where:
T - typename of component with setter
S - typename of component to inject
setter - public, non-static method in T with the non-const signature:
context<>::ptr<S>::type& setter();
Inject a component to a Java-style setter during component initialization
-------------------------------------------------------------------------
Declarative:
context<>::component<T>::arg_setter<S, &T::setter> setter_decl;
Procedural:
TBD
Where:
T - typename of component with setter
S - typename of component to inject
setter - public, non-static method in T with the non-const signature:
void setter(const context<>::ptr<S>::type& s);
BUILDING
========
Inject is a header-only library, which means it does not require building. Just
include "inject/inject.h" and compile.
To build the unit-tests and example code:
- install cmake >= 2.6
- install boost >= 1.47
- in the top-level directory, run: 'cmake -DCMAKE_BUILD_TYPE=Debug .' or
'-DCMAKE_BUILD_TYPE=Release .'
- make clean && make
Unit-tests executable is under: src/tests/inject/unit_tests
Example executable is under each example directory.
If you have Doxygen installed, you can run 'make doc' at the root folder to
generate the API documentation. it should generate to the doxygen/
subfolder.
COMPATIBILITY
=============
Inject was tested with:
- g++ 4.7.1
- clang++ 3.0-6
- MSVC 9 and 10
TODO
====
* Use std::shared_ptr<> when C++11 is available
* Use vardiac templates for constructor handling if C++11 is available
* Implicit component registration if possible (infer from functional
declarations)
* thread-safe singletons (with boost or C++11 STL if available)
* Implicit cast from ptr<S>::type so it could be assigned to straight setter
(i.e. S& setter() and void setter(const S& s), without ptr<S>::type wrapper)
* Test with XCode
OTHER C++ INJECTION LIBRARIES
=============================
* dicpp (https://bitbucket.org/cheez/dicpp/)
* cpp-resolver (http://sourceforge.net/projects/cpp-resolver/)
* Torgny (http://programmaticallyspeaking.blogspot.com/2010/04/beautiful-dependency-injection-in-c.html)
* QtIocContainer (http://sourceforge.net/projects/qtioccontainer/)
* hypodermic (http://code.google.com/p/hypodermic/)
* sauce (https://github.com/phs/sauce)
* wallaroo (https://code.google.com/p/wallaroo/)
LICENSE
=======
Copyright (c) 2012-2013 Itay Duvdevani
All rights reserved.
Inject is distributed under the MIT OSI license. For additional info, please
refer to: LICENSE or contact itay@duvdevani.com
You can’t perform that action at this time.