Sauce-0.10.1
A C++ Dependency Injection Framework
binding.h
1 #ifndef SAUCE_INTERNAL_BINDING_H_
2 #define SAUCE_INTERNAL_BINDING_H_
3 
4 #include <cassert>
5 #include <string>
6 
7 #include <sauce/injector.h>
8 #include <sauce/memory.h>
9 #include <sauce/named.h>
10 #include <sauce/internal/key.h>
11 #include <sauce/internal/opaque_binding.h>
12 #include <sauce/internal/resolved_binding.h>
13 #include <sauce/internal/type_id.h>
14 
15 namespace sauce {
16 namespace internal {
17 
21 template<typename Dependency_, typename Scope>
22 class Binding: public ResolvedBinding<Dependency_>, public InjectorFriend {
23 public:
24 
26  typedef typename Key<Dependency>::Ptr IfacePtr;
27  typedef typename ResolvedBinding<Dependency>::BindingPtr BindingPtr;
28 
29 private:
30 
31  std::string name;
32 
36  TypeId getScopeKey() const {
37  return typeIdOf<Scope>();
38  }
39 
45  virtual void inject(IfacePtr &, BindingPtr, InjectorPtr) const = 0;
46 
58  void get(IfacePtr & injected, BindingPtr binding, InjectorPtr injector) const {
59  bool unscoped = (getScopeKey() == typeIdOf<NoScope>()) || this->isModifier();
60 
61  if (unscoped || !probe<Dependency>(injector, injected, getScopeKey())) {
62  // injected is not null if and only if we are a modifier.
63  assert((injected.get() != NULL) == this->isModifier());
64 
65  inject(injected, binding, injector);
66  if (!unscoped) {
67  cache<Dependency>(injector, injected, getScopeKey());
68  }
69  }
70  }
71 
78  void eagerlyInject(OpaqueBindingPtr opaque, InjectorPtr injector) const {
79  if (getScopeKey() != typeIdOf<NoScope>()) {
80  BindingPtr binding = resolve<Dependency>(opaque);
81  TypeIds ids;
82  this->validateAcyclic(injector, ids);
83  IfacePtr injected;
84  get(injected, binding, injector);
85  }
86  }
87 
91  virtual void setDynamicDependencyNames(std::vector<std::string> const &) {}
92 
93 public:
94 
95  Binding():
96  name(unnamed()) {}
97 
98  virtual ~Binding() {}
99 
103  std::string getName() const {
104  return name;
105  }
106 
110  void setName(std::string const name) {
111  this->name = name;
112  }
113 
114 };
115 
116 }
117 
118 namespace i = ::sauce::internal;
119 
120 }
121 
122 #endif // SAUCE_INTERNAL_BINDING_H_
void setName(std::string const name)
Set the dynamic name of this binding.
Definition: binding.h:110
A binding for an acknowledged interface.
Definition: resolved_binding.h:20
Definition: binder.h:317
Definition: injector.h:196
Wrap dependency requests with Named to choose one of several (statically) named alternatives.
Definition: named.h:12
std::string getName() const
The dynamic name of this binding.
Definition: binding.h:103
virtual void validateAcyclic(sauce::shared_ptr< Injector >, TypeIds &) const =0
Establish that further dependencies do not introduce cycles with ones already accumulated.
A TypeSignature equipped with specific helper methods dealing in the hidden type. ...
Definition: type_id.h:34
The base class of all actual binding implementations.
Definition: binding.h:22
Definition: binder.h:21
A complete specification of a dependency request.
Definition: key.h:15
virtual bool isModifier() const
Does this binding modify an existing value?
Definition: opaque_binding.h:58