Skip to content

Instantly share code, notes, and snippets.

@laparca
Created June 30, 2014 15:03
Show Gist options
  • Save laparca/b17491593ff61bdf9dda to your computer and use it in GitHub Desktop.
Save laparca/b17491593ff61bdf9dda to your computer and use it in GitHub Desktop.
Proof of Concept of dependency injection in C++
#include <iostream>
#include <string>
#include <map>
#include <typeinfo>
namespace injection {
class instance_generator {
public:
virtual void* get() = 0;
};
template<typename T>
class instace_generator_impl : public instance_generator {
public:
void* get() {
return new T();
}
};
std::map<std::string, instance_generator*> info;
template<typename T>
void reg(std::string cl_name) {
std::cerr << "Registering " << typeid(T).name() << " for name " << cl_name << std::endl;
info.insert(std::map<std::string, instance_generator*>::value_type(cl_name, (instance_generator*)new instace_generator_impl<T>()));
}
template<typename T, typename On>
void reg() {
std::cerr << "Registering " << typeid(T).name() << " for name " << typeid(On).name() << std::endl;
info.insert(std::map<std::string, instance_generator*>::value_type(typeid(On).name(), (instance_generator*)new instace_generator_impl<T>()));
}
template<class T>
T* get(std::string cl_name) {
std::cerr << "Retrieving class type " << typeid(T).name() << " for name " << cl_name << std::endl;
auto ig = info[cl_name];
void *val = ig->get();
return static_cast<T*>(val);
}
}
template<class T, class On>
class inject {
T* object;
public:
inject() : object(injection::get<T>(typeid(On).name())) {}
T* operator->() {
return object;
}
template<typename... Types>
auto operator()(Types&&... values) -> decltype((*object)(std::forward<Types>(values)...)) {
return (*object)(std::forward<Types>(values)...);
}
};
class Service {
public:
virtual void do_something() = 0;
};
class HelloService : public Service {
public:
void do_something() {
std::cout << "Hello, World!" << std::endl;
}
};
class Bean {
inject<Service, Bean> my_service;
public:
Bean() {}
void call_me() {
my_service->do_something();
}
};
int main() {
injection::reg<HelloService, Bean>();
Bean b;
b.call_me();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment