Sauce-0.10.1
A C++ Dependency Injection Framework
clause.h
1 #ifndef SAUCE_CLAUSE_H_
2 #define SAUCE_CLAUSE_H_
3 
4 #include <string>
5 #include <vector>
6 
7 #include <sauce/exceptions.h>
8 #include <sauce/memory.h>
9 #include <sauce/named.h>
10 #include <sauce/internal/bindings.h>
11 #include <sauce/internal/instance_binding.h>
12 #include <sauce/internal/method_binding.h>
13 #include <sauce/internal/new_binding.h>
14 #include <sauce/internal/opaque_binding.h>
15 #include <sauce/internal/pending_thrower.h>
16 #include <sauce/internal/provider_binding.h>
17 
18 namespace sauce {
19 namespace internal {
20 
21 class ImplicitBindings;
22 
26 class ClauseState {
27  Bindings<ImplicitBindings> & bindings;
28  PendingThrower & pendingThrower;
29  OpaqueBindingPtr pendingBinding;
30  OpaqueBindingPtr providerBinding;
31  std::string dynamicName;
32  std::vector<std::string> dynamicDependencyNames;
33 
34 public:
35 
36  ClauseState(Bindings<ImplicitBindings> & bindings, PendingThrower & pendingThrower):
37  bindings(bindings),
38  pendingThrower(pendingThrower),
39  pendingBinding(),
40  providerBinding(),
41  dynamicName(unnamed()),
42  dynamicDependencyNames() {
43  pendingThrower.throwAnyPending();
44  }
45 
46  virtual ~ClauseState() {
47  if (pendingBinding.get() == NULL) {
48  return;
49  }
50 
51  pendingBinding->setName(dynamicName);
52  pendingBinding->setDynamicDependencyNames(dynamicDependencyNames);
53 
54  if (pendingBinding.get() != NULL) {
55  bindings.put(pendingBinding);
56  }
57 
58  if (providerBinding.get() != NULL) {
59  bindings.put(providerBinding);
60  }
61  }
62 
63  void bind(OpaqueBindingPtr pendingBinding) {
64  this->pendingBinding = pendingBinding;
65  }
66 
67  void bindProvider(OpaqueBindingPtr providerBinding) {
68  this->providerBinding = providerBinding;
69  }
70 
71  void setDynamicName(std::string const name) {
72  this->dynamicName = name;
73  }
74 
75  void bindDynamicDependencyName(unsigned int position, std::string const name) {
76  if (dynamicDependencyNames.size() <= position) {
77  dynamicDependencyNames.resize(position + 1, unnamed());
78  }
79  dynamicDependencyNames[position] = name;
80  }
81 
82  template<typename Exception>
83  void throwLater() {
84  pendingThrower.template throwLater<Exception>();
85  }
86 
87  void clearException() {
88  pendingThrower.clear();
89  }
90 };
91 
92 typedef sauce::shared_ptr<ClauseState> ClauseStatePtr;
93 
97 template<typename Dependency>
98 class Clause {
99  ClauseStatePtr state;
100 
101 protected:
102 
103  virtual void onComplete() {
105  }
106 
107  Clause():
108  state() {}
109 
110  Clause(ClauseStatePtr state):
111  state(state) {
113  }
114 
115  ClauseStatePtr getState() {
116  return state;
117  }
118 
119  template<typename Next>
120  Next pass(Next next) {
121  next.setState(state);
122  return next;
123  }
124 
125  void setDynamicName(std::string const name) {
126  state->setDynamicName(name);
127  }
128 
129  template<typename Exception>
130  void throwLater(Exception) {
131  state->template throwLater<Exception>();
132  }
133 
134  void bindDynamicDependencyName(unsigned int position, std::string const name) {
135  state->bindDynamicDependencyName(position, name);
136  }
137 
138 public:
139 
140  virtual ~Clause() {}
141 
142  Clause<Dependency> & naming(unsigned int position, std::string const name) {
143  this->bindDynamicDependencyName(position, name);
144  return *this;
145  }
146 
147  void setState(ClauseStatePtr state) {
148  this->state = state;
149  getState()->clearException();
150  onComplete();
151  }
152 };
153 
154 }
155 
156 namespace i = ::sauce::internal;
157 
158 }
159 
160 #endif // SAUCE_CLAUSE_H_
Thrown when a binding hasn't been completely specified for the given interface.
Definition: exceptions.h:49
Definition: binder.h:317
PendingThrow clear()
Clear and return any saved exception.
Definition: pending_thrower.h:58
void throwAnyPending()
Throw and clear any saved exception.
Definition: pending_thrower.h:46
A container for bindings.
Definition: bindings.h:50
Base class for parts of the fluent binding API.
Definition: clause.h:98
Definition: binder.h:21
Base class for all sauce exceptions.
Definition: exceptions.h:12
void put(OpaqueBindingPtr binding)
Insert the given binding.
Definition: bindings.h:70
The accumulated state passed between Clauses that ultimately results in a new Binding.
Definition: clause.h:26
A mixin to defer and throw pending exceptions.
Definition: pending_thrower.h:23