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
21namespace sauce {
22
26template<typename Dependency, typename Scope, typename Ctor, typename Allocator>
27class 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
37template<typename Dependency, typename Scope, typename Ctor>
38class 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
46public:
47
48 template<typename Allocator>
51 }
52};
53
57template<typename ProviderDependency, typename Scope, typename ProviderCtor>
58class 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
72public:
73
74 template<typename Allocator>
77 }
78};
79
83template<typename Dependency, typename Scope>
84class InClause: public i::Clause<Dependency> {
85 typedef typename i::Key<Dependency>::Iface Iface;
86 typedef typename i::Key<Dependency>::Name Name;
88
89public:
90
91 template<typename Ctor>
93 return this->pass(ToClause<Dependency, Scope, Ctor>());
94 }
95
96 template<typename ProviderCtor>
99 }
100};
101
102template<typename Dependency>
103class NamedClause;
104
105template<typename Iface>
106class BindClause;
107
111template<typename Dependency, typename Signature>
112class 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
133template<typename Dependency, typename Signature>
134class 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
160template<typename Dependency>
161class 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
171public:
172
173 ToInstanceClause(IfacePtr iface):
175 iface(iface) {}
176};
177
185template<typename Dependency>
186class 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;
191
192public:
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>
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>
227 return this->pass(InClause<Dependency, Scope>());
228 }
229
230 template<typename Ctor>
232 return this->pass(ToClause<Dependency, NoScope, Ctor>());
233 }
234
235 template<typename ProviderCtor>
238 }
239};
240
241class Binder;
242
246template<typename Iface>
247class BindClause: public i::Clause<Named<Iface, Unnamed> > {
248 typedef typename i::Key<Iface>::Ptr IfacePtr;
250
251 BindClause(i::ClauseStatePtr state):
253
254 friend class Binder;
255
256public:
257
258 template<typename Name>
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>
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>
306 return this->pass(ToClause<Named<Iface, Unnamed>, NoScope, Ctor>());
307 }
308
309 template<typename ProviderCtor>
312 }
313};
314
315class Modules;
316
317namespace internal {
318class ImplicitBindings;
319}
320
326
327 friend class Modules;
328
330 PendingThrower(),
331 bindings(bindings) {}
332
333public:
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_
Binds to a specific constructor and allocator.
Definition: binder.h:27
A builder that creates a single binding.
Definition: binder.h:247
Passed to modules to create bindings.
Definition: binder.h:324
BindClause< Iface > bind()
Begin binding the chosen interface.
Definition: binder.h:339
Scopes the binding.
Definition: binder.h:84
A factory that accepts Modules and creates Injectors.
Definition: modules.h:77
Names the binding.
Definition: binder.h:186
Wrap dependency requests with Named to choose one of several (statically) named alternatives.
Definition: named.h:12
The scope of unscoped bindings.
Definition: scopes.h:11
An interface for including custom factories in an Injector.
Definition: provider.h:21
i::Key< Dependency >::Iface Provides
Indicates to template magic that this type exposes sauce::shared_ptr<Provides> get().
Definition: provider.h:27
Binds to a specific constructor, allocating from the heap.
Definition: binder.h:38
Binds to a specific single instance.
Definition: binder.h:161
Binds to a specific method.
Definition: binder.h:112
Binds to a specific method with possible static dependency names.
Definition: binder.h:134
Binds to a provider with a specific constructor, allocating from the heap.
Definition: binder.h:58
The name of all statically unnamed dependencies.
Definition: named.h:17
A container for bindings.
Definition: bindings.h:50
Base class for parts of the fluent binding API.
Definition: clause.h:98
The accumulated state passed between Clauses that ultimately results in a new Binding.
Definition: clause.h:26
An injection that provides the value passed at construction.
Definition: instance_binding.h:17
A complete specification of a dependency request.
Definition: key.h:15
Definition: method_binding.h:14
Definition: new_binding.h:19
A mixin to defer and throw pending exceptions.
Definition: pending_thrower.h:23
An injection that provides from the configured provider.
Definition: provider_binding.h:18