13 changed files with 628 additions and 72 deletions
			
			
		@ -0,0 +1,62 @@ | 
				
			|||
/*! | 
				
			|||
@def QTMVVM_INJECT | 
				
			|||
 | 
				
			|||
@param classType The type of the property to be injected | 
				
			|||
@param name The name of the property to be injected | 
				
			|||
 | 
				
			|||
This macro creates an additional property that is detected by the QtMvvm::ServiceRegistry and | 
				
			|||
contains the information needed to inject the property automatically. For more details on | 
				
			|||
the property injection, see QtMvvm::ServiceRegistry | 
				
			|||
 | 
				
			|||
Sample code for usage: | 
				
			|||
@code{.cpp} | 
				
			|||
class MyClass : public QObject | 
				
			|||
{ | 
				
			|||
	Q_OBJECT | 
				
			|||
 | 
				
			|||
	Q_PROPERTY(IService* service READ service WRITE setService) | 
				
			|||
	QTMVVM_INJECT(IService*, service) | 
				
			|||
 | 
				
			|||
public: | 
				
			|||
	//... | 
				
			|||
} | 
				
			|||
@endcode | 
				
			|||
 | 
				
			|||
@note All properties that make use of interfaces must register the interfaces via | 
				
			|||
QtMvvm::registerInterfaceConverter | 
				
			|||
 | 
				
			|||
@sa #QTMVVM_INJECT_PROP, QtMvvm::registerInterfaceConverter, QtMvvm::ServiceRegistry | 
				
			|||
*/ | 
				
			|||
 | 
				
			|||
/*! | 
				
			|||
@def QTMVVM_INJECT_PROP | 
				
			|||
 | 
				
			|||
@param type The type of the property to be created | 
				
			|||
@param name The name of the property to be created | 
				
			|||
@param member The name of the member variable to use for the property | 
				
			|||
 | 
				
			|||
This macro is a shortcut for #QTMVVM_INJECT to create a property and mark it for injection in | 
				
			|||
one step. The property is created by using a member variable. This means it will have no public | 
				
			|||
member functions to access the property, only the property accessors itself. | 
				
			|||
 | 
				
			|||
Sample code for usage: | 
				
			|||
@code{.cpp} | 
				
			|||
class MyClass : public QObject | 
				
			|||
{ | 
				
			|||
	Q_OBJECT | 
				
			|||
 | 
				
			|||
	QTMVVM_INJECT_PROP(IService*, service, _service) | 
				
			|||
 | 
				
			|||
public: | 
				
			|||
	//... | 
				
			|||
 | 
				
			|||
private: | 
				
			|||
	IService* _service; | 
				
			|||
} | 
				
			|||
@endcode | 
				
			|||
 | 
				
			|||
@note All properties that make use of interfaces must register the interfaces via | 
				
			|||
QtMvvm::registerInterfaceConverter | 
				
			|||
 | 
				
			|||
@sa #QTMVVM_INJECT, QtMvvm::registerInterfaceConverter, QtMvvm::ServiceRegistry | 
				
			|||
*/ | 
				
			|||
@ -0,0 +1,418 @@ | 
				
			|||
/*! | 
				
			|||
@class QtMvvm::ServiceRegistry | 
				
			|||
 | 
				
			|||
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. | 
				
			|||
 | 
				
			|||
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: | 
				
			|||
 | 
				
			|||
@code{.cpp} | 
				
			|||
// service.h | 
				
			|||
class Service : public QObject | 
				
			|||
{ | 
				
			|||
	Q_OBJECT | 
				
			|||
 | 
				
			|||
public: | 
				
			|||
	Q_INVOKABLE explicit Service(QObject *parent = nullptr); //required signature | 
				
			|||
 | 
				
			|||
public Q_SLOTS: | 
				
			|||
	void baum(); | 
				
			|||
}; | 
				
			|||
 | 
				
			|||
// 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); | 
				
			|||
	QtMvvm::ServiceRegistry::instance()->registerObject<Service>(); | 
				
			|||
 | 
				
			|||
	//... | 
				
			|||
 | 
				
			|||
	auto myObj = new MyClass(parent); | 
				
			|||
	QtMvvm::ServiceRegistry::instance()->injectServices(myObj); | 
				
			|||
	// _service is now initialized via a valid Service | 
				
			|||
} | 
				
			|||
@endcode | 
				
			|||
 | 
				
			|||
The second example shows how to use it for interface based services and on objects that are | 
				
			|||
created via the registry: | 
				
			|||
 | 
				
			|||
@code{.cpp} | 
				
			|||
// 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; | 
				
			|||
}; | 
				
			|||
 | 
				
			|||
// 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>(); | 
				
			|||
	QtMvvm::ServiceRegistry::instance()->registerInterface<IService, Service>(); | 
				
			|||
 | 
				
			|||
	//... | 
				
			|||
 | 
				
			|||
	auto myObj = QtMvvm::ServiceRegistry::instance()->constructInjected<MyClass>(); | 
				
			|||
	// _service is now initialized via a valid IService | 
				
			|||
} | 
				
			|||
@endcode | 
				
			|||
 | 
				
			|||
@sa QtMvvm::registerInterfaceConverter, #QTMVVM_INJECT, #QTMVVM_INJECT_PROP, ViewModel | 
				
			|||
*/ | 
				
			|||
 | 
				
			|||
/*! | 
				
			|||
@fn QtMvvm::ServiceRegistry::registerInterface(bool) | 
				
			|||
 | 
				
			|||
@tparam TInterface The interface type to register the service for | 
				
			|||
@tparam TService The service to be registered for that interface. Must extend QObject and | 
				
			|||
implement TInterface | 
				
			|||
@param weak Specifies if the registration should be a weak one or a normal one | 
				
			|||
@throws ServiceExistsException If 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);` | 
				
			|||
 | 
				
			|||
@sa ServiceRegistry::registerObject, QtMvvm::registerInterfaceConverter, | 
				
			|||
ServiceRegistry::registerService, ServiceRegistry::service | 
				
			|||
*/ | 
				
			|||
 | 
				
			|||
/*! | 
				
			|||
@fn QtMvvm::ServiceRegistry::registerInterface(const TFunc &, bool) | 
				
			|||
 | 
				
			|||
@tparam TInterface The interface type to register the service for | 
				
			|||
@tparam TService The service to be registered for that interface. Must extend QObject and | 
				
			|||
implement TInterface | 
				
			|||
@tparam TFunc The function type of the `fn` parameter. | 
				
			|||
@param fn The function to be called to construct the service | 
				
			|||
@param weak Specifies if the registration should be a weak one or a normal one | 
				
			|||
@throws ServiceExistsException If 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: | 
				
			|||
@code{.cpp} | 
				
			|||
TService *fn(...); | 
				
			|||
@endcode | 
				
			|||
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. | 
				
			|||
 | 
				
			|||
@sa ServiceRegistry::registerObject, QtMvvm::registerInterfaceConverter, | 
				
			|||
ServiceRegistry::registerService, ServiceRegistry::service | 
				
			|||
*/ | 
				
			|||
 | 
				
			|||
/*! | 
				
			|||
@fn QtMvvm::ServiceRegistry::registerInterface(TService *, bool) | 
				
			|||
 | 
				
			|||
@tparam TInterface The interface type to register the service for | 
				
			|||
@tparam TService The service to be registered for that interface. Must extend QObject and | 
				
			|||
implement TInterface | 
				
			|||
@param service The service instance to be registered as service | 
				
			|||
@param weak Specifies if the registration should be a weak one or a normal one | 
				
			|||
@throws ServiceExistsException If 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. | 
				
			|||
 | 
				
			|||
@sa ServiceRegistry::registerObject, QtMvvm::registerInterfaceConverter, | 
				
			|||
ServiceRegistry::registerService, ServiceRegistry::service | 
				
			|||
*/ | 
				
			|||
 | 
				
			|||
/*! | 
				
			|||
@fn QtMvvm::ServiceRegistry::registerObject(bool) | 
				
			|||
 | 
				
			|||
@tparam TService The service to be registered by its own type. Must extend QObject | 
				
			|||
@param weak Specifies if the registration should be a weak one or a normal one | 
				
			|||
@throws ServiceExistsException If 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);` | 
				
			|||
 | 
				
			|||
@sa ServiceRegistry::registerInterface, ServiceRegistry::registerService, | 
				
			|||
ServiceRegistry::service | 
				
			|||
*/ | 
				
			|||
 | 
				
			|||
/*! | 
				
			|||
@fn QtMvvm::ServiceRegistry::registerObject(const TFunc &, bool) | 
				
			|||
 | 
				
			|||
@tparam TService The service to be registered by its own type. Must extend QObject | 
				
			|||
@tparam TFunc The function type of the `fn` parameter. | 
				
			|||
@param fn The function to be called to construct the service | 
				
			|||
@param weak Specifies if the registration should be a weak one or a normal one | 
				
			|||
@throws ServiceExistsException If 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: | 
				
			|||
@code{.cpp} | 
				
			|||
TService *fn(...); | 
				
			|||
@endcode | 
				
			|||
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. | 
				
			|||
 | 
				
			|||
@sa ServiceRegistry::registerInterface, ServiceRegistry::registerService, | 
				
			|||
ServiceRegistry::service | 
				
			|||
*/ | 
				
			|||
 | 
				
			|||
/*! | 
				
			|||
@fn QtMvvm::ServiceRegistry::registerObject(TService *, bool) | 
				
			|||
 | 
				
			|||
@tparam TService The service to be registered by its own type. Must extend QObject | 
				
			|||
@param service The service instance to be registered as service | 
				
			|||
@param weak Specifies if the registration should be a weak one or a normal one | 
				
			|||
@throws ServiceExistsException If 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. | 
				
			|||
 | 
				
			|||
@sa ServiceRegistry::registerInterface, ServiceRegistry::registerService, | 
				
			|||
ServiceRegistry::service | 
				
			|||
*/ | 
				
			|||
 | 
				
			|||
/*! | 
				
			|||
@fn QtMvvm::ServiceRegistry::registerService(const QByteArray &, const QMetaObject *, bool) | 
				
			|||
 | 
				
			|||
@param iid The interface id of the type to register the service for | 
				
			|||
@param metaObject The 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 | 
				
			|||
@param weak Specifies if the registration should be a weak one or a normal one | 
				
			|||
@throws ServiceExistsException If 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);` | 
				
			|||
 | 
				
			|||
@sa ServiceRegistry::registerObject, QtMvvm::registerInterface, ServiceRegistry::serviceObj | 
				
			|||
*/ | 
				
			|||
 | 
				
			|||
/*! | 
				
			|||
@fn QtMvvm::ServiceRegistry::registerService(const QByteArray &, const std::function<QObject*(const QObjectList &)> &, QByteArrayList, bool) | 
				
			|||
 | 
				
			|||
@param iid The interface id of the type to register the service for | 
				
			|||
@param fn The function to be called to construct the service | 
				
			|||
@param injectables The iids of the parameters to be passed to `fn` | 
				
			|||
@param weak Specifies if the registration should be a weak one or a normal one | 
				
			|||
@throws ServiceExistsException If 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. | 
				
			|||
 | 
				
			|||
@sa ServiceRegistry::registerObject, QtMvvm::registerInterface, ServiceRegistry::serviceObj | 
				
			|||
*/ | 
				
			|||
 | 
				
			|||
/*! | 
				
			|||
@fn QtMvvm::ServiceRegistry::service | 
				
			|||
 | 
				
			|||
@tparam TInterface The interface type get an instance of | 
				
			|||
@returns An object that implements the interface | 
				
			|||
@throws ServiceConstructionException If 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 | 
				
			|||
 | 
				
			|||
@sa ServiceRegistry::registerObject, QtMvvm::registerInterface, ServiceRegistry::serviceObj, | 
				
			|||
ServiceRegistry::injectServices, ServiceRegistry::constructInjected | 
				
			|||
*/ | 
				
			|||
 | 
				
			|||
/*! | 
				
			|||
@fn QtMvvm::ServiceRegistry::serviceObj | 
				
			|||
 | 
				
			|||
@param iid The interface id of the type to get an instance of | 
				
			|||
@returns An object that implements the interface specified by iid | 
				
			|||
@throws ServiceConstructionException If 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. | 
				
			|||
 | 
				
			|||
@sa ServiceRegistry::registerService, ServiceRegistry::serviceObj, | 
				
			|||
ServiceRegistry::injectServices, ServiceRegistry::constructInjected | 
				
			|||
*/ | 
				
			|||
 | 
				
			|||
/*! | 
				
			|||
@fn QtMvvm::ServiceRegistry::injectServices | 
				
			|||
 | 
				
			|||
@param object The object to inject properties into | 
				
			|||
@throws ServiceConstructionException If 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. | 
				
			|||
 | 
				
			|||
@sa ServiceRegistry::constructInjected, ServiceRegistry::service, #QTMVVM_INJECT, | 
				
			|||
#QTMVVM_INJECT_PROP | 
				
			|||
*/ | 
				
			|||
 | 
				
			|||
/*! | 
				
			|||
@fn QtMvvm::ServiceRegistry::constructInjected(QObject *) | 
				
			|||
 | 
				
			|||
@tparam TClass The type of object to be created, must extend QObject | 
				
			|||
@param parent The parent object of the created object | 
				
			|||
@returns A newly created instance of TClass. | 
				
			|||
@throws ServiceConstructionException If 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);` | 
				
			|||
 | 
				
			|||
@sa ServiceRegistry::injectServices, ServiceRegistry::service, #QTMVVM_INJECT, | 
				
			|||
#QTMVVM_INJECT_PROP | 
				
			|||
*/ | 
				
			|||
 | 
				
			|||
/*! | 
				
			|||
@fn QtMvvm::ServiceRegistry::constructInjected(const QMetaObject *, QObject *) | 
				
			|||
 | 
				
			|||
@param metaObject The metaobject of object type to be created, must extend QObject | 
				
			|||
@param parent The parent object of the created object | 
				
			|||
@returns A newly created instance of the given type. | 
				
			|||
@throws ServiceConstructionException If 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);` | 
				
			|||
 | 
				
			|||
@sa ServiceRegistry::injectServices, ServiceRegistry::service, #QTMVVM_INJECT, | 
				
			|||
#QTMVVM_INJECT_PROP | 
				
			|||
*/ | 
				
			|||
@ -0,0 +1,33 @@ | 
				
			|||
#ifndef QTMVVM_INJECTION_H | 
				
			|||
#define QTMVVM_INJECTION_H | 
				
			|||
 | 
				
			|||
#include "qtmvvmcore_global.h" | 
				
			|||
 | 
				
			|||
//! The primary namespace of the QtMvvm library
 | 
				
			|||
namespace QtMvvm { | 
				
			|||
 | 
				
			|||
//TODO sa in service registry
 | 
				
			|||
//! Registers QVariant converters from QObject to an interface type registered with Q_DECLARE_INTERFACE
 | 
				
			|||
template <typename TInterface> | 
				
			|||
inline void registerInterfaceConverter() { | 
				
			|||
	QMetaType::registerConverter<QObject*, TInterface*>([](QObject *o) { | 
				
			|||
		return qobject_cast<TInterface*>(o); | 
				
			|||
	}); | 
				
			|||
} | 
				
			|||
 | 
				
			|||
} | 
				
			|||
 | 
				
			|||
//! Mark a property for injection
 | 
				
			|||
#define QTMVVM_INJECT(classType, name) \ | 
				
			|||
	static inline QByteArray __qtmvvm_inject_##name() { \ | 
				
			|||
		return QtMvvm::__helpertypes::inject_iid<classType>(); \ | 
				
			|||
	} \ | 
				
			|||
	Q_PROPERTY(QByteArray __qtmvvm_inject_##name READ __qtmvvm_inject_##name STORED false SCRIPTABLE false DESIGNABLE false CONSTANT FINAL) | 
				
			|||
 | 
				
			|||
//! Create a for injection marked property based on a member
 | 
				
			|||
#define QTMVVM_INJECT_PROP(type, name, member) \ | 
				
			|||
	Q_PROPERTY(type name MEMBER member) \ | 
				
			|||
	QTMVVM_INJECT(type, name) | 
				
			|||
 | 
				
			|||
//! @file injection.h A header with injection related code
 | 
				
			|||
#endif // INJECTION_H
 | 
				
			|||
					Loading…
					
					
				
		Reference in new issue