Sauce-0.10.1: sauce/internal/base_injector.h Source File

Sauce-0.10.1 A C++ Dependency Injection Framework

- Main Page
- Classes
- Files

- File List

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
14 namespace sauce {
15
16 class Injector;
17 class Modules;
18
19 namespace internal {
20
21 template<typename ImplicitBindings>
22 class BaseInjector;
23
27 template<typename ImplicitBindings, typename Dependency>
28 class CircularDependencyGuard {
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 {
41 throw CircularDependencyExceptionFor<Dependency>();
42 }
43 }
44
45 ~CircularDependencyGuard() {
46 ids.erase(id);
47 }
48 };
49
50 template<typename ImplicitBindings>
51 class BaseInjector {
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
64 public:
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;
69 CircularDependencyGuard<ImplicitBindings, Normalized> guard(ids, name);
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
98 namespace i = ::sauce::internal;
99
100 }
101
102 #endif // SAUCE_INTERNAL_BASE_INJECTOR_H_