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
10namespace sauce {
11namespace internal {
12
13template<typename Dependency, typename Signature>
14class 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
93public:
94 typedef typename Inject::Method Method;
95private:
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
113public:
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
130namespace i = ::sauce::internal;
131
132}
133
134#endif // SAUCE_INTERNAL_METHOD_BINDING_H_
Definition: apply_variadic.h:34
The base class of all actual binding implementations.
Definition: binding.h:22
A complete specification of a dependency request.
Definition: key.h:15
Definition: method_binding.h:14
void inject(IfacePtr &injected, BindingPtr, InjectorPtr injector) const
Inject an Iface.
Definition: method_binding.h:121