1 #ifndef SAUCE_INJECTOR_H_
2 #define SAUCE_INJECTOR_H_
7 #include <sauce/memory.h>
8 #include <sauce/named.h>
9 #include <sauce/scopes.h>
10 #include <sauce/internal/base_injector.h>
11 #include <sauce/internal/key.h>
12 #include <sauce/internal/locker_factory.h>
13 #include <sauce/internal/scope_cache.h>
14 #include <sauce/internal/type_id.h>
22 class ImplicitBindings;
24 typedef sauce::shared_ptr<Injector> InjectorPtr;
30 sauce::weak_ptr<Injector> weak;
31 i::InjectorPtr
const next;
32 sauce::shared_ptr<i::BaseInjector<i::ImplicitBindings> >
const base;
45 scopeKey(i::typeIdOf<SingletonScope>()),
51 void setSelfPtr(i::InjectorPtr shared) {
52 assert(shared.get() ==
this);
56 i::InjectorPtr getSelf()
const {
57 i::InjectorPtr
self = weak.lock();
58 assert(
self.
get() ==
this);
62 template<
typename Dependency>
63 void validateAcyclic(
bool validateProviding, i::InjectorPtr injector, i::TypeIds & ids, std::string
const name) {
64 if (base.get() == NULL) {
65 next->validateAcyclic<Dependency>(validateProviding, injector, ids, name);
67 base->validateAcyclic<Dependency>(validateProviding, injector, ids, name);
71 template<
typename Dependency>
73 if (base.get() == NULL) {
74 next->inject<Dependency>(injected, injector, name);
76 base->inject<Dependency>(injected, injector, name);
83 sauce::auto_ptr<i::Lock> acquireLock() {
84 if (base.get() == NULL) {
85 return next->acquireLock();
87 return base->acquireLock();
91 template<
typename Scope>
92 void eagerlyInject(i::InjectorPtr injector) {
93 if (base.get() == NULL) {
94 next->eagerlyInject<Scope>(injector);
96 base->eagerlyInject<Scope>(injector);
100 template<
typename Dependency>
102 if (scopeKey == dependencyScopeKey) {
103 scopeCache.template put<Dependency>(pointer);
104 }
else if (next.get() == NULL) {
107 next->cache<Dependency>(pointer, dependencyScopeKey);
111 template<
typename Dependency>
113 if (scopeKey == dependencyScopeKey) {
114 return scopeCache.template get<Dependency>(out);
115 }
else if (next.get() == NULL) {
119 return next->probe<Dependency>(out, dependencyScopeKey);
123 template<
typename Scope>
124 bool alreadyInScope()
const {
125 if (scopeKey == i::typeIdOf<Scope>()) {
127 }
else if (next.get() == NULL) {
130 return next->alreadyInScope<Scope>();
136 template<
typename Dependency>
141 sauce::auto_ptr<i::Lock> lock = acquireLock();
144 bool validateProviding = (injected.get() == NULL);
145 validateAcyclic<Normalized>(validateProviding, getSelf(), ids, name);
147 inject<Normalized>(injected, getSelf(), name);
150 template<
typename Iface,
typename Name>
152 inject<Named<Iface, Name> >(injected, name);
155 template<
typename Dependency>
158 inject<Dependency>(injected, name);
162 template<
typename Iface,
typename Name>
164 return get<Named<Iface, Name> >(name);
167 template<
typename Scope>
168 i::InjectorPtr enter()
const {
169 if (alreadyInScope<Scope>()) {
173 i::InjectorPtr scoped(
new Injector(i::typeIdOf<Scope>(), getSelf()));
174 scoped->setSelfPtr(scoped);
178 i::InjectorPtr exit()
const {
179 if (next.get() == NULL) {
186 template<
typename Scope>
187 void eagerlyInject() {
188 sauce::auto_ptr<i::Lock> lock = acquireLock();
189 eagerlyInject<Scope>(getSelf());
199 template<
typename Dependency>
200 void validateAcyclicHelper(InjectorPtr injector, TypeIds & ids, std::string
const name)
const {
201 injector->validateAcyclic<Dependency>(
true, injector, ids, name);
204 template<
typename Dependency>
205 void injectHelper(
typename Key<Dependency>::Ptr & injected, InjectorPtr injector, std::string
const name)
const {
206 injector->inject<Dependency>(injected, injector, name);
209 template<
typename Dependency>
211 injector->template cache<Dependency>(injected, scope);
214 template<
typename Dependency>
216 return injector->template probe<Dependency>(injected, scope);
225 #endif // SAUCE_INJECTOR_H_
Definition: scope_cache.h:19
Thrown when re-entering the given scope, which is already open.
Definition: exceptions.h:103
Definition: injector.h:196
Wrap dependency requests with Named to choose one of several (statically) named alternatives.
Definition: named.h:12
virtual void throwOutOfScopeException() const
Throw an OutOfScopeException appropriate for the hidden type, assuming it is a Scope.
Definition: type_id.h:64
Definition: base_injector.h:22
A factory that accepts Modules and creates Injectors.
Definition: modules.h:77
A TypeSignature equipped with specific helper methods dealing in the hidden type. ...
Definition: type_id.h:34
Thrown when exiting the singleton scope.
Definition: exceptions.h:111
A complete specification of a dependency request.
Definition: key.h:15
Definition: injector.h:27