Sauce-0.10.1
A C++ Dependency Injection Framework
method_binding.h
1 #ifndef SAUCE_INTERNAL_METHOD_BINDING_H_
2 #define SAUCE_INTERNAL_METHOD_BINDING_H_
3 
4 #include <sauce/injector.h>
5 #include <sauce/scopes.h>
6 #include <sauce/internal/apply_variadic.h>
7 #include <sauce/internal/binding.h>
8 #include <sauce/internal/resolved_binding.h>
9 
10 namespace sauce {
11 namespace internal {
12 
13 template<typename Dependency, typename Signature>
14 class MethodBinding: public Binding<Dependency, NoScope> {
15 
17 
21  struct MethodBindingFriend {
22  template<typename T>
23  void validateAcyclicHelper(MethodBinding_ const & binding, InjectorPtr injector, TypeIds & ids, std::string name) {
24  binding.template validateAcyclicHelper<T>(injector, ids, name);
25  }
26 
27  template<typename T>
28  typename Key<T>::Ptr injectHelper(MethodBinding_ const & binding, InjectorPtr injector, std::string name) {
29  typename Key<T>::Ptr injected;
30  binding.template injectHelper<typename i::Key<T>::Normalized>(injected, injector, name);
31  return injected;
32  }
33  };
34 
35  friend class MethodBindingFriend;
36 
37  struct InjectParameters {
38  struct Passed {
39  MethodBinding_ const & binding;
40  InjectorPtr & injector;
41 
42  Passed(MethodBinding_ const & binding, InjectorPtr & injector):
43  binding(binding), injector(injector) {}
44  };
45 
46  template<typename T, int i>
47  struct Parameter: public MethodBindingFriend {
48  typedef typename Key<T>::Ptr Type;
49 
50  template<typename Passed>
51  Type yield(Passed passed) {
52  MethodBinding_ const & binding = passed.binding;
53  InjectorPtr & injector = passed.injector;
54  std::string dependencyName = binding.dynamicDependencyNames[i];
55 
56  return this->MethodBindingFriend::template injectHelper<T>(binding, injector, dependencyName);
57  }
58  };
59  };
60 
61  typedef typename Key<Dependency>::Iface Iface;
62  typedef typename Key<Dependency>::Ptr IfacePtr;
64 
65  std::vector<std::string> dynamicDependencyNames;
66 
67  struct ValidateAcyclicParameters {
68  struct Passed {
69  MethodBinding_ const & binding;
70  InjectorPtr & injector;
71  TypeIds & ids;
72 
73  Passed(MethodBinding_ const & binding, InjectorPtr & injector, TypeIds & ids):
74  binding(binding), injector(injector), ids(ids) {}
75  };
76 
77  template<typename T, int i>
78  struct Parameter: public MethodBindingFriend {
79  typedef typename Key<T>::Ptr Type;
80 
81  template<typename Passed>
82  void observe(Passed passed) {
83  MethodBinding_ const & binding = passed.binding;
84  InjectorPtr & injector = passed.injector;
85  TypeIds & ids = passed.ids;
86  std::string dependencyName = binding.dynamicDependencyNames[i];
87 
88  this->MethodBindingFriend::template validateAcyclicHelper<T>(binding, injector, ids, dependencyName);
89  }
90  };
91  };
92 
93 public:
94  typedef typename Inject::Method Method;
95 private:
96 
97  Method method;
98 
99  bool isModifier() const {
100  return true;
101  }
102 
103  void validateAcyclic(InjectorPtr injector, TypeIds & ids) const {
104  typename ValidateAcyclicParameters::Passed passed(*this, injector, ids);
105  observeMethod<ValidateAcyclicParameters, Signature>(method, passed);
106  }
107 
108  void setDynamicDependencyNames(std::vector<std::string> const & dynamicDependencyNames) {
109  this->dynamicDependencyNames = dynamicDependencyNames;
110  this->dynamicDependencyNames.resize(Inject::arity(), unnamed());
111  }
112 
113 public:
114 
115  typedef typename ResolvedBinding<Dependency>::BindingPtr BindingPtr;
116 
117  explicit MethodBinding(Method method):
118  dynamicDependencyNames(Inject::arity(), unnamed()),
119  method(method) {}
120 
121  void inject(IfacePtr & injected, BindingPtr, InjectorPtr injector) const {
122  typename InjectParameters::Passed passed(*this, injector);
123  applyMethod<InjectParameters, Signature>(*injected.get(), method, passed);
124  }
125 
126 };
127 
128 }
129 
130 namespace i = ::sauce::internal;
131 
132 }
133 
134 #endif // SAUCE_INTERNAL_METHOD_BINDING_H_
Definition: binder.h:317
void inject(IfacePtr &injected, BindingPtr, InjectorPtr injector) const
Inject an Iface.
Definition: method_binding.h:121
The base class of all actual binding implementations.
Definition: binding.h:22
Definition: binder.h:21
Definition: method_binding.h:14
A complete specification of a dependency request.
Definition: key.h:15
Definition: apply_variadic.h:34