Home

Awesome

injeqt

Simple dependency injection framework for Qt

Documentation

Documentation available at github.

Example

Here is example of what can be done using injeqt:

#include <injeqt/injector.h>
#include <injeqt/module.h>

#include <QtCore/QObject>
#include <iostream>
#include <memory>
#include <string>

class hello_service : public QObject
{
	Q_OBJECT

public:
	hello_service() {}
	virtual ~hello_service() {}

	std::string say_hello() const
	{
		return {"Hello"};
	}
};

class world_service : public QObject
{
	Q_OBJECT

public:
	world_service() {}
	virtual ~world_service() {}

	std::string say_world() const
	{
		return {"World"};
	}
};

class hello_factory : public QObject
{
	Q_OBJECT

public:
	Q_INVOKABLE hello_factory() {}
	virtual ~hello_factory() {}

	Q_INVOKABLE hello_service * create_service()
	{
		return new hello_service{};
	}
};

class hello_client : public QObject
{
	Q_OBJECT

public:
	Q_INVOKABLE hello_client() : _s{nullptr}, _w{nullptr} {}
	virtual ~hello_client() {}

	std::string say() const
	{
		return _s->say_hello() + " " + _w->say_world() + "!";
	}

private slots:
	INJEQT_INIT void init()
	{
		std::cerr << "all services set" << std::endl;
	}

	INJEQT_DONE void done()
	{
		std::cerr << "ready for destruction" << std::endl;
	}

	INJEQT_SET void set_hello_service(hello_service *s)
	{
		_s = s;
	}

	INJEQT_SET void set_world_service(world_service *w)
	{
		_w = w;
	}

private:
	hello_service *_s;
	world_service *_w;

};

class module : public injeqt::module
{
public:
	explicit module()
	{
		_w = std::unique_ptr<world_service>{new world_service{}};

		add_type<hello_client>();
		add_type<hello_factory>();
		add_factory<hello_service, hello_factory>();
		add_ready_object<world_service>(_w.get());
	}

	virtual ~module() {}

private:
	std::unique_ptr<world_service> _w;

};

int main()
{
	auto modules = std::vector<std::unique_ptr<injeqt::module>>{};
	modules.emplace_back(std::unique_ptr<injeqt::module>{new module{}});

	auto injector = injeqt::injector{std::move(modules)};
	auto client = injector.get<hello_client>();
	auto hello = client->say();

	std::cout << hello << std::endl;
}

#include "hello-world.moc"

In that example we can see two main services names hello_service and world_service. There is also client of these names hello_client. In module class we configure how we create and access these instances.

hello_client is added using add_type function. It means that injeqt will try to create it using default constructor. We provide that by declaration of Q_INVOKABLE hello_client() (Q_INVOKABLE is requires by Qt's meta object system).

hello_service is added using add_factory function. It means that injeqt will first try to create a hello_factory object, then it will look for a method of that objet that returns hello_service object. It will find Q_INVOKABLE hello_service * create_service() and use it.

To be able to create hello_factory injeqt must know about it, so we also add it using add_type method.

Last, world_service, is added as a ready object - provided from outside of injeqt scope.

In main method list of conifguration modules are passed to newly created injector instance. From that moment, we can use injector to create and manage our services. Just one line below an hello_client instance is required. This is what happens next: