I'm trying to create some tool for easier dependency injection in c++14, here is one of my concepts using std::tuple.
template <class... Types>
class injector
{
public:
injector(Types... i) { injected_ = std::tuple<Types...>(i...); }
protected:
template <class T>
T *injected()
{
return std::get<T *>(injected_);
}
private:
std::tuple<Types...> injected_;
};
using component_injector = injector<scene *, entity *, foo *>;
class component : component_injector
{
public:
component(component_injector injected) : component_injector(injected) {};
virtual ~component(){};
void method()
{
injected<scene>()->method();
injected<foo>()->method();
}
};
int main(int argc, char *argv[])
{
scene s;
entity e;
foo f;
component c({&s, &e, &f});
c.method();
return 0;
}
Is it good idea to create dependence this way? It has some limitations, for example I cannot have two dependencies of the same type etc. but code of useful part (component class) seems to be much clearer. The injected types should be replaced by interfaces but the real types are used directly here for simplicity.
-
\$\begingroup\$ Easier? Why is that easier? \$\endgroup\$Loki Astari– Loki Astari2017年07月25日 14:50:52 +00:00Commented Jul 25, 2017 at 14:50
1 Answer 1
- I don't think that makes it easier (or cleaner)
- You are injecting pointers (which begs to ask ownership)
- You should be preferring encapsulation over inheritance.
If I was doing it normally:
class component
{
Scene& scene;
Entity& entity;
Foo& foo;
public:
component(Scene& s, Entity& e, Foo& f)
: scene(s)
, entity(e)
, foo(f)
{}
virtual ~component(){};
void method()
{
scene->method();
foo->method();
}
};
int main()
{
scene s;
entity e;
foo f;
component c(s, e, f});
c.method();
}
This seems much cleaner than your method (where you introduce another level of inheritance).