Sauce-0.10.1
A C++ Dependency Injection Framework
base_injector.h
1#ifndef SAUCE_INTERNAL_BASE_INJECTOR_H_
2#define SAUCE_INTERNAL_BASE_INJECTOR_H_
3
4#include <sauce/exceptions.h>
5#include <sauce/memory.h>
6#include <sauce/named.h>
7#include <sauce/provider.h>
8#include <sauce/internal/bindings.h>
9#include <sauce/internal/key.h>
10#include <sauce/internal/locker_factory.h>
11#include <sauce/internal/self_injector.h>
12#include <sauce/internal/type_id.h>
13
14namespace sauce {
15
16class Injector;
17class Modules;
18
19namespace internal {
20
21template<typename ImplicitBindings>
22class BaseInjector;
23
27template<typename ImplicitBindings, typename Dependency>
29 friend class BaseInjector<ImplicitBindings>;
30
31 TypeIds & ids;
32 NamedTypeId id;
33
34 CircularDependencyGuard(TypeIds & ids, std::string const name):
35 ids(ids),
36 id(namedTypeIdOf<Dependency>(name)) {
37 TypeIds::iterator i = ids.find(id);
38 if (i == ids.end()) {
39 ids.insert(i, id);
40 } else {
42 }
43 }
44
46 ids.erase(id);
47 }
48};
49
50template<typename ImplicitBindings>
52 typedef sauce::auto_ptr<LockFactory> LockFactoryPtr;
53 typedef sauce::shared_ptr<Injector> InjectorPtr;
54
55 Bindings<ImplicitBindings> const bindings;
56 LockFactoryPtr lockFactory;
57
58 friend class ::sauce::Modules;
59
60 BaseInjector(Bindings<ImplicitBindings> const & bindings, LockFactoryPtr lockFactory):
61 bindings(bindings),
62 lockFactory(lockFactory) {}
63
64public:
65
66 template<typename Dependency>
67 void validateAcyclic(bool validateProviding, InjectorPtr injector, TypeIds & ids, std::string const name) const {
68 typedef typename Key<Dependency>::Normalized Normalized;
70 bindings.template validateAcyclic<Normalized>(validateProviding, injector, ids, name);
71 }
72
73 template<typename Dependency>
74 void inject(typename Key<Dependency>::Ptr & injected, InjectorPtr injector, std::string const name) const {
75 typedef typename Key<Dependency>::Normalized Normalized;
76 typedef typename Key<Dependency>::Iface Iface;
77 bindings.template get<Normalized>(injected, injector, name);
78 SelfInjector<Iface> selfInjector;
79 selfInjector.setSelf(injected);
80 }
81
82 template<typename Scope>
83 void eagerlyInject(InjectorPtr injector) const {
84 bindings.template eagerlyInject<Scope>(injector);
85 }
86
90 sauce::auto_ptr<Lock> acquireLock() {
91 sauce::auto_ptr<Lock> lock = lockFactory->createLock();
92 return lock;
93 }
94};
95
96}
97
98namespace i = ::sauce::internal;
99
100}
101
102#endif // SAUCE_INTERNAL_BASE_INJECTOR_H_
Thrown when a dependency cycle is found for the given interface.
Definition: exceptions.h:67
Definition: base_injector.h:51
sauce::auto_ptr< Lock > acquireLock()
Create an RAII synchronization lock.
Definition: base_injector.h:90
A container for bindings.
Definition: bindings.h:50
Detects circular dependencies on behalf of injectors.
Definition: base_injector.h:28
Attempts to supply a Binding when none is found for a dependency.
Definition: implicit_bindings.h:53
A complete specification of a dependency request.
Definition: key.h:15
If a type requests injection of its own smart pointer, do so.
Definition: self_injector.h:16