Sauce-0.10.1
A C++ Dependency Injection Framework
modules.h
1 #ifndef SAUCE_MODULES_H_
2 #define SAUCE_MODULES_H_
3 
4 #include <sauce/binder.h>
5 #include <sauce/injector.h>
6 #include <sauce/memory.h>
7 #include <sauce/internal/base_injector.h>
8 #include <sauce/internal/resolved_binding.h>
9 #include <sauce/internal/bindings.h>
10 #include <sauce/internal/implicit_bindings.h>
11 #include <sauce/internal/locker_factory.h>
12 
13 namespace sauce {
14 
22  mutable Binder * binder;
23 
27  class BinderGuard {
28  AbstractModule const * module;
29  Binder * previousBinder;
30 
31  friend class AbstractModule;
32 
33  BinderGuard(AbstractModule const * module, Binder * binder):
34  module(module),
35  previousBinder(module->binder) {
36  module->binder = binder;
37  }
38 
39  ~BinderGuard() {
40  module->binder = previousBinder;
41  }
42  };
43 
44  friend class BinderGuard;
45 
46 protected:
47 
49  binder(NULL) {}
50 
54  virtual void configure() const = 0;
55 
59  template<typename Iface>
61  return binder->bind<Iface>();
62  }
63 
64 public:
65 
66  virtual ~AbstractModule() {}
67 
68  void operator()(Binder & binder) const {
69  BinderGuard guard(this, &binder);
70  configure();
71  }
72 };
73 
77 class Modules {
79  Binder binder;
80 
81  sauce::shared_ptr<Injector> createInjector(sauce::auto_ptr<i::LockFactory> lockFactory) const {
82  sauce::shared_ptr<i::BaseInjector<i::ImplicitBindings> > base(
83  new i::BaseInjector<i::ImplicitBindings>(bindings, lockFactory));
84  sauce::shared_ptr<Injector> injector(new Injector(base));
85  injector->setSelfPtr(injector);
86  return injector;
87  }
88 
89 public:
90 
95  bindings(),
96  binder(bindings) {}
97 
104  Modules & add(void (* module)(Binder &)) {
105  module(binder);
106  binder.throwAnyPending();
107  return *this;
108  }
109 
118  template<typename Module>
119  Modules & add() {
120  Module module;
121  module(binder);
122  binder.throwAnyPending();
123  return *this;
124  }
125 
134  template<typename Module>
135  Modules & add(Module & module) {
136  module(binder);
137  binder.throwAnyPending();
138  return *this;
139  }
140 
147  sauce::shared_ptr<Injector> createInjector() const {
148  sauce::auto_ptr<i::LockFactory> lockFactory(new i::NullLockFactory());
149  return createInjector(lockFactory);
150  }
151 
158  template<typename Locker, typename Lockable>
159  sauce::shared_ptr<Injector> createInjector(Lockable & lockable) const {
160  sauce::auto_ptr<i::LockFactory> lockFactory(new i::LockerLockFactory<Locker, Lockable>(lockable));
161  return createInjector(lockFactory);
162  }
163 
164 };
165 
166 }
167 
168 #endif // SAUCE_MODULES_H_