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 
14 namespace sauce {
15 
16 class Injector;
17 class Modules;
18 
19 namespace internal {
20 
21 template<typename ImplicitBindings>
23 
27 template<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 
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_
Definition: binder.h:317
Definition: base_injector.h:22
sauce::auto_ptr< Lock > acquireLock()
Create an RAII synchronization lock.
Definition: base_injector.h:90
A container for bindings.
Definition: bindings.h:50
Named< Dependency, Unnamed > Normalized
Note Normalized is not Iface, but Named.
Definition: key.h:27
Thrown when a dependency cycle is found for the given interface.
Definition: exceptions.h:67
Definition: binder.h:21
Detects circular dependencies on behalf of injectors.
Definition: base_injector.h:28