Skip to content

Commit 6fde20a

Browse files
committed
Di update
1 parent 45218ab commit 6fde20a

File tree

2 files changed

+74
-21
lines changed

2 files changed

+74
-21
lines changed

Source/Library/h/DependencyInjector.hpp

+60-21
Original file line numberDiff line numberDiff line change
@@ -14,42 +14,73 @@ namespace sd
1414
class DependencyInjector
1515
{
1616
private:
17-
template <class T> struct Constructor
17+
template <typename T> struct FunctionTraits;
18+
19+
template <typename R, typename... Args> struct FunctionTraits<std::function<R(Args...)>>
1820
{
19-
T ctor;
20-
Constructor(T ctor) : ctor(ctor) {}
21+
static const size_t nargs = sizeof...(Args);
22+
23+
typedef R result_type;
24+
25+
template <size_t i> struct arg
26+
{
27+
typedef typename std::tuple_element<i, std::tuple<Args...>>::type type;
28+
};
2129
};
2230

2331
struct IConstructionInfo
2432
{
2533
virtual std::type_index getTypeIndex() const = 0;
2634

27-
virtual const std::vector<std::type_index> &getParamsTypeIndexes() const = 0;
35+
virtual const std::vector<std::type_index> getParamsTypeIndexes() const = 0;
2836

2937
virtual void *construct(const std::vector<void *> &params) const = 0;
3038

3139
virtual ~IConstructionInfo() {}
3240
};
3341

34-
template <class Type, class Param1> class ConstructionInfo final : public IConstructionInfo
42+
template <typename R, typename... Args> class ConstructionInfo final : public IConstructionInfo
3543
{
3644
private:
37-
std::type_index _typeIndex = typeid(Type);
38-
std::vector<std::type_index> _params;
39-
Type *(*_ctor)(Param1 *);
45+
using ConstructorTraits = FunctionTraits<std::function<R(Args...)>>;
46+
std::function<R(Args...)> _constructor;
4047

4148
public:
42-
ConstructionInfo(Constructor<Type *(*)(Param1 *)> constructor)
43-
{
44-
_ctor = constructor.ctor;
45-
_params = {typeid(Param1)};
46-
}
49+
ConstructionInfo(const std::function<R(Args...)> &constructor) { _constructor = constructor; }
4750

48-
std::type_index getTypeIndex() const { return _typeIndex; }
51+
std::type_index getTypeIndex() const { return typeid(typename ConstructorTraits::result_type); }
4952

50-
const std::vector<std::type_index> &getParamsTypeIndexes() const { return _params; };
53+
const std::vector<std::type_index> getParamsTypeIndexes() const
54+
{
55+
if constexpr (ConstructorTraits::nargs == 0)
56+
{
57+
return {};
58+
}
59+
else if constexpr (ConstructorTraits::nargs == 1)
60+
{
61+
return {typeid(typename ConstructorTraits::template arg<0>::type)};
62+
}
63+
else if constexpr (ConstructorTraits::nargs == 2)
64+
{
65+
return {typeid(typename ConstructorTraits::template arg<0>::type),
66+
typeid(typename ConstructorTraits::template arg<1>::type)};
67+
}
68+
};
5169

52-
void *construct(const std::vector<void *> &params) const { return (*_ctor)((Param1 *)params[0]); };
70+
void *construct(const std::vector<void *> &params) const
71+
{
72+
if constexpr (ConstructorTraits::nargs == 0)
73+
{
74+
return _constructor();
75+
}
76+
else if constexpr (ConstructorTraits::nargs == 1)
77+
{
78+
return _constructor((typename ConstructorTraits::template arg<0>::type)(params[0]));
79+
}
80+
else if constexpr (ConstructorTraits::nargs == 2)
81+
{
82+
}
83+
};
5384
};
5485

5586
private:
@@ -60,12 +91,12 @@ namespace sd
6091
template <class I, class T> void addSingeleton()
6192
{
6293
// todo check if T inherits from/implements I
63-
auto cons = Constructor{T::constructor};
64-
auto i = new ConstructionInfo(cons);
65-
_registered.insert({typeid(I), std::unique_ptr<IConstructionInfo>(i)});
94+
std::function<decltype(T::constructor)> ff{&T::constructor};
95+
auto i = new ConstructionInfo(ff);
96+
_registered.insert({typeid(I *), std::unique_ptr<IConstructionInfo>(i)});
6697
}
6798

68-
template <class I> I *get() { return (I *)get(typeid(I)); }
99+
template <class I> I *get() { return (I *)get(typeid(I *)); }
69100

70101
void build()
71102
{
@@ -113,7 +144,15 @@ namespace sd
113144
IConstructionInfo *getRegistered(std::type_index index)
114145
{
115146
auto pair = _registered.find(index);
116-
return pair != _registered.end() ? pair->second.get() : nullptr;
147+
if (pair != _registered.end())
148+
{
149+
auto &ob = pair->second;
150+
return ob.get();
151+
}
152+
else
153+
{
154+
return nullptr;
155+
}
117156
}
118157
};
119158
} // namespace sd

Tests/DependencyInjectorTest.cpp

+14
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,21 @@
44

55
#include "DependencyInjector.hpp"
66

7+
#define Injectable() static
78
struct TestA
89
{
910
static TestA *constructor() { return new TestA(); };
11+
12+
int gg = 100;
13+
14+
Injectable() TestA() {}
1015
};
1116

1217
struct TestB
1318
{
1419
static TestB *constructor(TestA *a) { return new TestB(); };
20+
21+
int ff = 100;
1522
};
1623

1724
class DependencyInjector : public ::testing::Test
@@ -36,4 +43,11 @@ TEST_F(DependencyInjector, ExampleTest)
3643
{
3744
di.addSingeleton<TestA, TestA>();
3845
di.addSingeleton<TestB, TestB>();
46+
47+
di.build();
48+
49+
TestA *a = di.get<TestA>();
50+
51+
TestB *b = di.get<TestB>();
52+
int g = 0;
3953
}

0 commit comments

Comments
 (0)