Sauce-0.10.1: sauce/internal/method_binding.h Source File

Sauce-0.10.1 A C++ Dependency Injection Framework

- Main Page
- Classes
- Files

- File List

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
16 typedef MethodBinding<Dependency, Signature> MethodBinding_;
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;
63 typedef ApplyMethod<InjectParameters, Signature> Inject;
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_