Sauce-0.10.1
A C++ Dependency Injection Framework
binder.h
1 #ifndef SAUCE_BINDER_H_
2 #define SAUCE_BINDER_H_
3 
4 #include <memory>
5 #include <string>
6 #include <utility>
7 
8 #include <sauce/named.h>
9 #include <sauce/provider.h>
10 #include <sauce/scopes.h>
11 #include <sauce/internal/bindings.h>
12 #include <sauce/internal/clause.h>
13 #include <sauce/internal/implicit_provider_binding.h>
14 #include <sauce/internal/injector_binding.h>
15 #include <sauce/internal/key.h>
16 #include <sauce/internal/new_binding.h>
17 #include <sauce/internal/opaque_binding.h>
18 #include <sauce/internal/pending_thrower.h>
19 #include <sauce/internal/provider_binding.h>
20 
21 namespace sauce {
22 
26 template<typename Dependency, typename Scope, typename Ctor, typename Allocator>
27 class AllocateFromClause: public i::Clause<Dependency> {
28  virtual void onComplete() {
29  i::OpaqueBindingPtr pendingBinding(new i::NewBinding<Dependency, Scope, Ctor, Allocator>());
30  this->getState()->bind(pendingBinding);
31  }
32 };
33 
37 template<typename Dependency, typename Scope, typename Ctor>
38 class ToClause: public i::Clause<Dependency> {
39  typedef typename i::Key<Dependency>::Iface Iface;
40 
41  virtual void onComplete() {
42  i::OpaqueBindingPtr pendingBinding(new i::NewBinding<Dependency, Scope, Ctor, std::allocator<int> >());
43  this->getState()->bind(pendingBinding);
44  }
45 
46 public:
47 
48  template<typename Allocator>
51  }
52 };
53 
57 template<typename ProviderDependency, typename Scope, typename ProviderCtor>
58 class ToProviderClause: public i::Clause<ProviderDependency> {
59  void onComplete() {
61  typedef typename Provider::Provides Iface;
62  typedef typename i::Key<ProviderDependency>::Name Name;
63  typedef Named<Iface, Name> ProvidedDependency;
64 
65  i::OpaqueBindingPtr pendingBinding(new i::NewBinding<ProviderDependency, Scope, ProviderCtor, std::allocator<int> >());
66  this->getState()->bind(pendingBinding);
67 
68  i::OpaqueBindingPtr providerBinding(new i::ProviderBinding<ProvidedDependency, Scope, ProviderDependency>());
69  this->getState()->bindProvider(providerBinding);
70  }
71 
72 public:
73 
74  template<typename Allocator>
77  }
78 };
79 
83 template<typename Dependency, typename Scope>
84 class InClause: public i::Clause<Dependency> {
85  typedef typename i::Key<Dependency>::Iface Iface;
86  typedef typename i::Key<Dependency>::Name Name;
88 
89 public:
90 
91  template<typename Ctor>
93  return this->pass(ToClause<Dependency, Scope, Ctor>());
94  }
95 
96  template<typename ProviderCtor>
99  }
100 };
101 
102 template<typename Dependency>
104 
105 template<typename Iface>
107 
111 template<typename Dependency, typename Signature>
112 class ToMethodClause: public i::Clause<Dependency> {
114  typedef typename MethodBinding_::Method Method;
115  Method method;
116 
117  friend class NamedClause<Dependency>;
118  friend class BindClause<typename i::Key<Dependency>::Iface>;
119 
120  void onComplete() {
121  i::OpaqueBindingPtr methodBinding(new MethodBinding_(method));
122  this->getState()->bind(methodBinding);
123  }
124 
125  ToMethodClause(Method method):
127  method(method) {}
128 };
129 
133 template<typename Dependency, typename Signature>
134 class ToMethodNamingClause: public i::Clause<Dependency> {
136  typedef typename MethodBinding_::Method Method;
137  Method method;
138 
139  friend class NamedClause<Dependency>;
140  friend class BindClause<typename i::Key<Dependency>::Iface>;
141 
142  void onComplete() {
143  i::OpaqueBindingPtr methodBinding(new MethodBinding_(method));
144  this->getState()->bind(methodBinding);
145  }
146 
147  ToMethodNamingClause(Method method):
149  method(method) {}
150 };
151 
160 template<typename Dependency>
161 class ToInstanceClause: public i::Clause<Dependency> {
163  typedef typename i::Key<Dependency>::Ptr IfacePtr;
164  IfacePtr iface;
165 
166  void onComplete() {
167  i::OpaqueBindingPtr instanceBinding(new InstanceBinding_(iface));
168  this->getState()->bind(instanceBinding);
169  }
170 
171 public:
172 
173  ToInstanceClause(IfacePtr iface):
175  iface(iface) {}
176 };
177 
185 template<typename Dependency>
186 class NamedClause: public i::Clause<Dependency> {
187  typedef typename i::Key<Dependency>::Iface Iface;
188  typedef typename i::Key<Dependency>::Ptr IfacePtr;
189  typedef typename i::Key<Dependency>::Name Name;
190  typedef Named<Provider<Iface>, Name> ProviderDependency;
191 
192 public:
193 
194  ToInstanceClause<Dependency> toInstance(IfacePtr iface) {
195  return this->pass(ToInstanceClause<Dependency>(iface));
196  }
197 
198  template<typename Method>
199  ToMethodClause<Dependency, Method> toMethod(Method method) {
200  return this->pass(ToMethodClause<Dependency, Method>(method));
201  }
202 
203  template<typename Signature>
204  ToMethodNamingClause<Dependency, Signature> toMethodNaming(
205  typename ToMethodNamingClause<Dependency, Signature>::Method method) {
206  return this->pass(ToMethodNamingClause<Dependency, Signature>(method));
207  }
208 
209  template<typename SetDependency>
210  ToMethodNamingClause<Dependency, void(Iface::*) (SetDependency)> setting(
211  typename ToMethodNamingClause<Dependency, void(Iface::*) (SetDependency)>::Method method,
212  std::string name = unnamed()) {
213  ToMethodNamingClause<Dependency, void(Iface::*) (SetDependency)> toMethodNamingClause(method);
214  toMethodNamingClause = this->pass(toMethodNamingClause);
215  toMethodNamingClause.bindDynamicDependencyName(0, name);
216  return toMethodNamingClause;
217  }
218 
219  template<typename Iface, typename Name>
220  ToMethodNamingClause<Dependency, void(Iface::*) (Named<Iface, Name>)> setting(
221  typename ToMethodNamingClause<Dependency, void(Iface::*) (Named<Iface, Name>)>::Method method) {
222  return this->pass(ToMethodNamingClause<Dependency, void(Iface::*) (Named<Iface, Name>)>(method));
223  }
224 
225  template<typename Scope>
226  InClause<Dependency, Scope> in() {
227  return this->pass(InClause<Dependency, Scope>());
228  }
229 
230  template<typename Ctor>
231  ToClause<Dependency, NoScope, Ctor> to() {
232  return this->pass(ToClause<Dependency, NoScope, Ctor>());
233  }
234 
235  template<typename ProviderCtor>
236  ToProviderClause<ProviderDependency, NoScope, ProviderCtor> toProvider() {
237  return this->pass(ToProviderClause<ProviderDependency, NoScope, ProviderCtor>());
238  }
239 };
240 
241 class Binder;
242 
246 template<typename Iface>
247 class BindClause: public i::Clause<Named<Iface, Unnamed> > {
248  typedef typename i::Key<Iface>::Ptr IfacePtr;
249  typedef Named<Provider<Iface>, Unnamed> ProviderDependency;
250 
251  BindClause(i::ClauseStatePtr state):
252  i::Clause<Named<Iface, Unnamed> >(state) {}
253 
254  friend class Binder;
255 
256 public:
257 
258  template<typename Name>
259  NamedClause<Named<Iface, Name> > named() {
260  return this->pass(NamedClause<Named<Iface, Name> >());
261  }
262 
263  NamedClause<Named<Iface, Unnamed> > named(std::string const name) {
264  this->setDynamicName(name);
265  return this->pass(NamedClause<Named<Iface, Unnamed> >());
266  }
267 
268  ToInstanceClause<Named<Iface, Unnamed> > toInstance(IfacePtr iface) {
269  return this->pass(ToInstanceClause<Named<Iface, Unnamed> >(iface));
270  }
271 
272  template<typename Method>
273  ToMethodClause<Named<Iface, Unnamed>, Method> toMethod(Method method) {
274  return this->pass(ToMethodClause<Named<Iface, Unnamed>, Method>(method));
275  }
276 
277  template<typename Signature>
278  ToMethodNamingClause<Named<Iface, Unnamed>, Signature> toMethodNaming(
279  typename ToMethodNamingClause<Named<Iface, Unnamed>, Signature>::Method method) {
280  return this->pass(ToMethodNamingClause<Named<Iface, Unnamed>, Signature>(method));
281  }
282 
283  template<typename SetDependency>
284  ToMethodNamingClause<Named<Iface, Unnamed>, void(Iface::*) (SetDependency)> setting(
285  typename ToMethodNamingClause<Named<Iface, Unnamed>, void(Iface::*) (SetDependency)>::Method method,
286  std::string name = unnamed()) {
287  ToMethodNamingClause<Named<Iface, Unnamed>, void(Iface::*) (SetDependency)> toMethodNamingClause(method);
288  toMethodNamingClause = this->pass(toMethodNamingClause);
289  toMethodNamingClause.bindDynamicDependencyName(0, name);
290  return toMethodNamingClause;
291  }
292 
293  template<typename SetIface, typename Name>
294  ToMethodNamingClause<Named<Iface, Unnamed>, void(Iface::*) (Named<SetIface, Name>)> setting(
295  typename ToMethodNamingClause<Named<Iface, Unnamed>, void(Iface::*) (Named<SetIface, Name>)>::Method method) {
296  return this->pass(ToMethodNamingClause<Named<Iface, Unnamed>, void(Iface::*) (Named<SetIface, Name>)>(method));
297  }
298 
299  template<typename Scope>
300  InClause<Named<Iface, Unnamed>, Scope> in() {
301  return this->pass(InClause<Named<Iface, Unnamed>, Scope>());
302  }
303 
304  template<typename Ctor>
305  ToClause<Named<Iface, Unnamed>, NoScope, Ctor> to() {
306  return this->pass(ToClause<Named<Iface, Unnamed>, NoScope, Ctor>());
307  }
308 
309  template<typename ProviderCtor>
310  ToProviderClause<ProviderDependency, NoScope, ProviderCtor> toProvider() {
311  return this->pass(ToProviderClause<ProviderDependency, NoScope, ProviderCtor>());
312  }
313 };
314 
315 class Modules;
316 
317 namespace internal {
318 class ImplicitBindings;
319 }
320 
324 class Binder: public i::PendingThrower {
326 
327  friend class Modules;
328 
330  PendingThrower(),
331  bindings(bindings) {}
332 
333 public:
334 
338  template<typename Iface>
340  i::ClauseStatePtr clauseState(new i::ClauseState(bindings, *this));
341  BindClause<Iface> bindClause(clauseState);
342  return bindClause;
343  }
344 };
345 
346 }
347 
348 #endif // SAUCE_BINDER_H_
BindClause< Iface > bind()
Begin binding the chosen interface.
Definition: binder.h:339
Binds to a specific constructor and allocator.
Definition: binder.h:27
Definition: binder.h:317
Wrap dependency requests with Named to choose one of several (statically) named alternatives.
Definition: named.h:12
Passed to modules to create bindings.
Definition: binder.h:324
i::Key< Dependency >::Iface Provides
Indicates to template magic that this type exposes sauce::shared_ptr get().
Definition: provider.h:27
Binds to a specific method.
Definition: binder.h:112
Names the binding.
Definition: binder.h:103
A builder that creates a single binding.
Definition: binder.h:106
A factory that accepts Modules and creates Injectors.
Definition: modules.h:77
Scopes the binding.
Definition: binder.h:84
Binds to a specific single instance.
Definition: binder.h:161
An injection that provides from the configured provider.
Definition: provider_binding.h:18
Binds to a provider with a specific constructor, allocating from the heap.
Definition: binder.h:58
An injection that provides the value passed at construction.
Definition: instance_binding.h:17
Definition: new_binding.h:19
Base class for parts of the fluent binding API.
Definition: clause.h:98
Binds to a specific method with possible static dependency names.
Definition: binder.h:134
Definition: binder.h:21
The accumulated state passed between Clauses that ultimately results in a new Binding.
Definition: clause.h:26
Definition: method_binding.h:14
A mixin to defer and throw pending exceptions.
Definition: pending_thrower.h:23
A complete specification of a dependency request.
Definition: key.h:15
An interface for including custom factories in an Injector.
Definition: provider.h:15
Binds to a specific constructor, allocating from the heap.
Definition: binder.h:38