Skip to content

Instantly share code, notes, and snippets.

@wtrsltnk
Created April 10, 2021 13:44
Show Gist options
  • Save wtrsltnk/aafc26f8f885b08917d52be0a02184c3 to your computer and use it in GitHub Desktop.
Save wtrsltnk/aafc26f8f885b08917d52be0a02184c3 to your computer and use it in GitHub Desktop.
This is an example of how I think DI can work in c++. Due to missing reflection, you still need to construct the objects yourself with a lambda passed to the Register<T>() method..
#include <functional>
#include <map>
#include <memory>
#include <string>
#include <typeindex>
#include <typeinfo>
typedef void* Object;
typedef std::function<Object(class ServiceCollection&)> ServiceBuilder;
class ServiceCollection
{
public:
template<class T>
std::unique_ptr<T> Resolve()
{
auto found = _services.find(typeid(T));
if (found != _services.end())
{
auto ptr = found->second(*this);
return std::unique_ptr<T>(reinterpret_cast<T*>(ptr));
}
return nullptr;
}
template<class T>
void Register(
ServiceBuilder func)
{
auto found = _services.find(typeid(T));
if (found != _services.end())
{
return;
}
_services.emplace(typeid(T), func);
}
private:
std::map<const std::type_index, ServiceBuilder> _services;
};
class Test
{
public:
void Run(){ printf("This works from Test!\n"); }
};
class TestTest
{
public:
TestTest(std::unique_ptr<Test> t) : _t(std::move(t)) { }
void Run(){ _t->Run(); }
std::unique_ptr<Test> _t;
};
int main()
{
ServiceCollection services;
services.Register<Test>(
[] (ServiceCollection &sc) -> Object
{
return new Test();
});
services.Register<TestTest>(
[] (ServiceCollection &sc) -> Object
{
return new TestTest(sc.Resolve<Test>());
});
auto t = services.Resolve<TestTest>();
t->Run();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment