QtMvvm  1.0.0
A mvvm oriented library for Qt, to create Projects for Widgets and Quick in parallel
Public Member Functions | Static Public Member Functions | List of all members
QtMvvm::ServiceRegistry Class Reference

A singleton to prepare services for dependency injection and to access them. More...

#include <serviceregistry.h>

Public Member Functions

template<typename TInterface >
bool isRegistered () const
 Checks if a given interface or service is already registered.
 
bool isRegistered (const QByteArray &iid) const
 Checks if a given interface or service is already registered.
 
template<typename TInterface , typename TService >
void registerInterface (bool weak=false)
 Register a service for its interface via the type. More...
 
template<typename TInterface , typename TService , typename TFunc >
void registerInterface (const TFunc &fn, bool weak=false)
 Register a service for its interface via a constructor function. More...
 
template<typename TInterface , typename TService >
void registerInterface (TService *service, bool weak=false)
 Register a service for its interface via an already existing instance. More...
 
template<typename TService >
void registerObject (bool weak=false)
 Register a service via its type. More...
 
template<typename TService , typename TFunc >
void registerObject (const TFunc &fn, bool weak=false)
 Register a service via a constructor function. More...
 
template<typename TService >
void registerObject (TService *service, bool weak=false)
 Register a service via an already existing instance. More...
 
void registerService (const QByteArray &iid, const QMetaObject *metaObject, bool weak=false)
 Register a service by an iid via their metadata. More...
 
void registerService (const QByteArray &iid, const std::function< QObject *(const QObjectList &)> &fn, QByteArrayList injectables, bool weak=false)
 Register a service by an iid via a generalized constructor function. More...
 
template<typename TInterface >
TInterface * service ()
 Returns the service for the given interface. More...
 
QObjectserviceObj (const QByteArray &iid)
 Returns the service for the given iid. More...
 
void injectServices (QObject *object)
 Inject services for all injectable properties on object. More...
 
template<typename TClass >
TClass * constructInjected (QObject *parent=nullptr)
 Constructs a new instance of TClass with properties injected. More...
 
QObjectconstructInjected (const QMetaObject *metaObject, QObject *parent=nullptr)
 Constructs a new instance of metaObject with properties injected. More...
 

Static Public Member Functions

static ServiceRegistryinstance ()
 Returns the ServiceRegistry singleton instance.
 

Detailed Description

A singleton to prepare services for dependency injection and to access them.

This is the class responsible for the dependency injection (DI) part. All services registered with the registry are available for DI. When using lazy initialization, services themselves can also have dependencies to be injected. When the registry creates them it will automatically inject them. Automatic DI is also done for ViewModel created by the CoreApp.

Note
If a service has a slot named qtmvvm_init() it is called automatically by the registry right after all dependant services have been injected.

The following example shows how to use DI. The first shows how to use it with a simple, interface-less service for an already created object:

// service.h
class Service : public QObject
{
Q_OBJECT
public:
Q_INVOKABLE explicit Service(QObject *parent = nullptr); //required signature
public Q_SLOTS:
void baum();
void qtmvvm_init(); //is called by the registry
};
// myclass.h
class MyClass : public QObject
{
Q_OBJECT
QTMVVM_INJECT_PROP(Service*, service, _service)
//...
private:
Service *_service;
};
//main.cpp
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//...
auto myObj = new MyClass(parent);
// _service is now initialized via a valid Service
}

The second example shows how to use it for interface based services and on objects that are created via the registry:

// iservice.h
class IService
{
public:
virtual inline ~IService() = default;
public Q_SLOTS:
virtual void baum() = 0;
};
#define IServiceIid "com.example.myapp.IService"
Q_DECLARE_INTERFACE(IService, IServiceIid)
// service.h
class Service : public QObject, public IService
{
Q_OBJECT
Q_INTERFACES(IService)
public:
Q_INVOKABLE explicit Service(QObject *parent = nullptr); //required signature
public Q_SLOTS:
void baum() override;
void qtmvvm_init(); //is called by the registry
};
// myclass.h
class MyClass : public QObject
{
Q_OBJECT
QTMVVM_INJECT_PROP(IService*, service, _service)
public:
Q_INVOKABLE MyClass(QObject *parent = nullptr); //required signature
//...
private:
IService *_service;
};
//main.cpp
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QtMvvm::registerInterfaceConverter<IService>();
//...
// _service is now initialized via a valid IService
}
See also
QtMvvm::registerInterfaceConverter, QTMVVM_INJECT, QTMVVM_INJECT_PROP, ViewModel

Definition at line 17 of file serviceregistry.h.

Member Function Documentation

◆ constructInjected() [1/2]

template<typename TClass >
QtMvvm::ServiceRegistry::constructInjected ( QObject parent = nullptr)

Constructs a new instance of TClass with properties injected.

Template Parameters
TClassThe type of object to be created, must extend QObject
Parameters
parentThe parent object of the created object
Returns
A newly created instance of TClass.
Exceptions
ServiceConstructionExceptionIf the registry failed to create an instance that needs to be injected into the object

First the method creates a new instance of TClass, then loads all services that are needed to inject into properties of the object that are marked for injection via QTMVVM_INJECT. If any lazy service has not been created yet, it is created on the fly and then injected. The returned object is parented to the parent object. If that is null it is owned by the caller.

Attention
For this to work, the TClass must have an invokable constructor with the following signature: Q_INVOKABLE explicit TClass(QObject *parent = nullptr);
See also
ServiceRegistry::injectServices, ServiceRegistry::service, QTMVVM_INJECT, QTMVVM_INJECT_PROP

Definition at line 219 of file serviceregistry.h.

◆ constructInjected() [2/2]

QtMvvm::ServiceRegistry::constructInjected ( const QMetaObject metaObject,
QObject parent = nullptr 
)

Constructs a new instance of metaObject with properties injected.

Parameters
metaObjectThe metaobject of object type to be created, must extend QObject
parentThe parent object of the created object
Returns
A newly created instance of the given type.
Exceptions
ServiceConstructionExceptionIf the registry failed to create an instance that needs to be injected into the object

First the method creates a new instance of metaObject, then loads all services that are needed to inject into properties of the object that are marked for injection via QTMVVM_INJECT. If any lazy service has not been created yet, it is created on the fly and then injected. The returned object is parented to the parent object. If that is null it is owned by the caller.

Attention
For this to work, the class defined by metaObject must have an invokable constructor with the following signature: Q_INVOKABLE explicit TClass(QObject *parent = nullptr);
See also
ServiceRegistry::injectServices, ServiceRegistry::service, QTMVVM_INJECT, QTMVVM_INJECT_PROP

◆ injectServices()

QtMvvm::ServiceRegistry::injectServices ( QObject object)

Inject services for all injectable properties on object.

Parameters
objectThe object to inject properties into
Exceptions
ServiceConstructionExceptionIf the registry failed to create an instance that needs to be injected into the object

Loads all services that are needed to inject into properties of the object that are marked for injection via QTMVVM_INJECT. If any lazy service has not been created yet, it is created on the fly and then injected.

See also
ServiceRegistry::constructInjected, ServiceRegistry::service, QTMVVM_INJECT, QTMVVM_INJECT_PROP

◆ registerInterface() [1/3]

template<typename TInterface , typename TService >
QtMvvm::ServiceRegistry::registerInterface ( bool  weak = false)

Register a service for its interface via the type.

Template Parameters
TInterfaceThe interface type to register the service for
TServiceThe service to be registered for that interface. Must extend QObject and implement TInterface
Parameters
weakSpecifies if the registration should be a weak one or a normal one
Exceptions
ServiceExistsExceptionIf a non-weak service has already been registered for TInterface

If the function returns successfully, from now on a service of the given type can be accessed via the registry for the interface. The service is lazy initialized an will be created as soon as it is requested for the first time. If it has any injectable properties, they will be automatically injected on construction.

If the service is registered as weak, registering another service for the same interface will not throw an exception but instead discard (and delete) this one.

Attention
Make shure to register TInterface via QtMvvm::registerInterfaceConverter, otherwise injection for the interface is not possible. In addition to this, TService must have an invokable constructor with the following signature: Q_INVOKABLE explicit TService(QObject *parent = nullptr);
See also
ServiceRegistry::registerObject, QtMvvm::registerInterfaceConverter, ServiceRegistry::registerService, ServiceRegistry::service

Definition at line 155 of file serviceregistry.h.

◆ registerInterface() [2/3]

template<typename TInterface , typename TService , typename TFunc >
QtMvvm::ServiceRegistry::registerInterface ( const TFunc &  fn,
bool  weak = false 
)

Register a service for its interface via a constructor function.

Template Parameters
TInterfaceThe interface type to register the service for
TServiceThe service to be registered for that interface. Must extend QObject and implement TInterface
TFuncThe function type of the fn parameter.
Parameters
fnThe function to be called to construct the service
weakSpecifies if the registration should be a weak one or a normal one
Exceptions
ServiceExistsExceptionIf a non-weak service has already been registered for TInterface

If the function returns successfully, from now on a service of the given type can be accessed via the registry for the interface. The service is lazy initialized an will be created as soon as it is requested for the first time. It is created by calling the given fn function.

fn must have the following signature:

TService *fn(...);

TService is the template parameter of this function. The arguments are variable, but if arguments are present, they all must be pointers of types that are injectable via the registry. When the function is called internally, the registry will "inject" all services as parameters of this function.

If the service is registered as weak, registering another service for the same interface will not throw an exception but instead discard (and delete) this one.

Attention
Make shure to register TInterface via QtMvvm::registerInterfaceConverter, otherwise injection for the interface is not possible.
See also
ServiceRegistry::registerObject, QtMvvm::registerInterfaceConverter, ServiceRegistry::registerService, ServiceRegistry::service

Definition at line 162 of file serviceregistry.h.

◆ registerInterface() [3/3]

template<typename TInterface , typename TService >
QtMvvm::ServiceRegistry::registerInterface ( TService *  service,
bool  weak = false 
)

Register a service for its interface via an already existing instance.

Template Parameters
TInterfaceThe interface type to register the service for
TServiceThe service to be registered for that interface. Must extend QObject and implement TInterface
Parameters
serviceThe service instance to be registered as service
weakSpecifies if the registration should be a weak one or a normal one
Exceptions
ServiceExistsExceptionIf a non-weak service has already been registered for TInterface

If the function returns successfully, from now on a service of the given type can be accessed via the registry for the interface. The service instance is from that point on owned by the registry. No DI is performed on the passed service.

If the service is registered as weak, registering another service for the same interface will not throw an exception but instead discard (and delete) this one.

Attention
Make shure to register TInterface via QtMvvm::registerInterfaceConverter, otherwise injection for the interface is not possible.
See also
ServiceRegistry::registerObject, QtMvvm::registerInterfaceConverter, ServiceRegistry::registerService, ServiceRegistry::service

Definition at line 171 of file serviceregistry.h.

◆ registerObject() [1/3]

template<typename TService >
QtMvvm::ServiceRegistry::registerObject ( bool  weak = false)

Register a service via its type.

Template Parameters
TServiceThe service to be registered by its own type. Must extend QObject
Parameters
weakSpecifies if the registration should be a weak one or a normal one
Exceptions
ServiceExistsExceptionIf a non-weak service has already been registered for TService

If the function returns successfully, from now on a service of the given type can be accessed via the registry. The service is lazy initialized an will be created as soon as it is requested for the first time. If it has any injectable properties, they will be automatically injected on construction.

If the service is registered as weak, registering another service for the same TService will not throw an exception but instead discard (and delete) this one.

Attention
In order to be able to create the service, TService must have an invokable constructor with the following signature: Q_INVOKABLE explicit TService(QObject *parent = nullptr);
See also
ServiceRegistry::registerInterface, ServiceRegistry::registerService, ServiceRegistry::service

Definition at line 185 of file serviceregistry.h.

◆ registerObject() [2/3]

template<typename TService , typename TFunc >
QtMvvm::ServiceRegistry::registerObject ( const TFunc &  fn,
bool  weak = false 
)

Register a service via a constructor function.

Template Parameters
TServiceThe service to be registered by its own type. Must extend QObject
TFuncThe function type of the fn parameter.
Parameters
fnThe function to be called to construct the service
weakSpecifies if the registration should be a weak one or a normal one
Exceptions
ServiceExistsExceptionIf a non-weak service has already been registered for TService

If the function returns successfully, from now on a service of the given type can be accessed via the registry. The service is lazy initialized an will be created as soon as it is requested for the first time. It is created by calling the given fn function.

fn must have the following signature:

TService *fn(...);

TService is the template parameter of this function. The arguments are variable, but if arguments are present, they all must be pointers of types that are injectable via theregistry. When the function is called internally, the registry will "inject" all services as parameters of this function.

If the service is registered as weak, registering another service for the same TService will not throw an exception but instead discard (and delete) this one.

See also
ServiceRegistry::registerInterface, ServiceRegistry::registerService, ServiceRegistry::service

Definition at line 192 of file serviceregistry.h.

◆ registerObject() [3/3]

template<typename TService >
QtMvvm::ServiceRegistry::registerObject ( TService *  service,
bool  weak = false 
)

Register a service via an already existing instance.

Template Parameters
TServiceThe service to be registered by its own type. Must extend QObject
Parameters
serviceThe service instance to be registered as service
weakSpecifies if the registration should be a weak one or a normal one
Exceptions
ServiceExistsExceptionIf a non-weak service has already been registered for TService

If the function returns successfully, from now on a service of the given type can be accessed via the registry. The service instance is from that point on owned by the registry. No DI is performed on the passed service.

If the service is registered as weak, registering another service for the same TService will not throw an exception but instead discard (and delete) this one.

Attention
Make shure to register TInterface via QtMvvm::registerInterfaceConverter, otherwise injection for the interface is not possible.
See also
ServiceRegistry::registerInterface, ServiceRegistry::registerService, ServiceRegistry::service

Definition at line 201 of file serviceregistry.h.

◆ registerService() [1/2]

QtMvvm::ServiceRegistry::registerService ( const QByteArray iid,
const QMetaObject metaObject,
bool  weak = false 
)

Register a service by an iid via their metadata.

Parameters
iidThe interface id of the type to register the service for
metaObjectThe metaobject of the service to be registered for that interface. Must extend QObject and implement the interface of iid, unless it is the id of the service itself
weakSpecifies if the registration should be a weak one or a normal one
Exceptions
ServiceExistsExceptionIf a non-weak service has already been registered for the iid

If the function returns successfully, from now on a service of the given metobject can be accessed via the registry for the iid. The service is lazy initialized an will be created as soon as it is requested for the first time. If it has any injectable properties, they will be automatically injected on construction.

If the service is registered as weak, registering another service for the same iid will not throw an exception but instead discard (and delete) this one.

Attention
In order to be able to create the service, the class defined by the metaobject must have an invokable constructor with the following signature: Q_INVOKABLE explicit Service(QObject *parent = nullptr);
See also
ServiceRegistry::registerObject, QtMvvm::registerInterface, ServiceRegistry::serviceObj

◆ registerService() [2/2]

QtMvvm::ServiceRegistry::registerService ( const QByteArray iid,
const std::function< QObject *(const QObjectList &)> &  fn,
QByteArrayList  injectables,
bool  weak = false 
)

Register a service by an iid via a generalized constructor function.

Parameters
iidThe interface id of the type to register the service for
fnThe function to be called to construct the service
injectablesThe iids of the parameters to be passed to fn
weakSpecifies if the registration should be a weak one or a normal one
Exceptions
ServiceExistsExceptionIf a non-weak service has already been registered for the iid

If the function returns successfully, from now on a service of the given type can be accessed via the registry for the interface. The service is lazy initialized an will be created as soon as it is requested for the first time. It is created by calling the given fn function.

The function must return an object that implements the interface of iid, unless it is the id of the service itself. The arguments are passed as object list and are determined by the injectables parameter. That is a list of iids. When the function is called internally, the registry will "inject" all services found by the iids as parameters of this function, comnined to a list of objects.

If the service is registered as weak, registering another service for the same iid will not throw an exception but instead discard (and delete) this one.

See also
ServiceRegistry::registerObject, QtMvvm::registerInterface, ServiceRegistry::serviceObj

◆ service()

template<typename TInterface >
QtMvvm::ServiceRegistry::service ( )

Returns the service for the given interface.

Template Parameters
TInterfaceThe interface type get an instance of
Returns
An object that implements the interface
Exceptions
ServiceConstructionExceptionIf the registry failed to create an instance for that interface

If the service is lazy inizialized and not created yet, the registry will do so. The returned service is owned by the registry. Be careful with weak services, as they may be deleted at any time. For normal services, this is never the case.

Note
TInterface can either be an actual interface or a service type, depending on what you registered it for (i.e. TInterface of the registerInterface() method and TService of the registerObject() method
See also
ServiceRegistry::registerObject, QtMvvm::registerInterface, ServiceRegistry::serviceObj, ServiceRegistry::injectServices, ServiceRegistry::constructInjected

Definition at line 213 of file serviceregistry.h.

◆ serviceObj()

QtMvvm::ServiceRegistry::serviceObj ( const QByteArray iid)

Returns the service for the given iid.

Parameters
iidThe interface id of the type to get an instance of
Returns
An object that implements the interface specified by iid
Exceptions
ServiceConstructionExceptionIf the registry failed to create an instance for that interface

If the service is lazy inizialized and not created yet, the registry will do so. The returned service is owned by the registry. Be careful with weak services, as they may be deleted at any time. For normal services, this is never the case.

Note
iid must be the identity the service has been registered for. This depends on the type itself and how it was registered.
See also
ServiceRegistry::registerService, ServiceRegistry::serviceObj, ServiceRegistry::injectServices, ServiceRegistry::constructInjected

The documentation for this class was generated from the following files: