├── .gitignore ├── CMakeLists.txt ├── QInjection.pro ├── README.md ├── src ├── .qmake2cmake │ └── subdir-of ├── CMakeLists.txt ├── dep_global.h ├── dependencycreator.cpp ├── dependencycreator.h ├── dependencyinjector.cpp ├── dependencyinjector.h ├── dependencypointer.cpp ├── dependencypointer.h ├── dependencypool.cpp ├── dependencypool.h ├── src.pri └── src.pro └── tests ├── .qmake2cmake └── subdir-of ├── CMakeLists.txt ├── NewAPI ├── .qmake2cmake │ └── subdir-of ├── CMakeLists.txt ├── NewAPI.pro └── tst_newapi.cpp ├── auto_create ├── .qmake2cmake │ └── subdir-of ├── CMakeLists.txt ├── auto_create.pro └── tst_create.cpp ├── common ├── adder.cpp ├── adder.h ├── constholder.cpp └── constholder.h ├── main ├── .qmake2cmake │ └── subdir-of ├── CMakeLists.txt ├── lifetimereporter.cpp ├── lifetimereporter.h ├── main.pro ├── tst_main.cpp └── tst_main.h └── tests.pro /.gitignore: -------------------------------------------------------------------------------- 1 | # C++ objects and libs 2 | 3 | *.slo 4 | *.lo 5 | *.o 6 | *.a 7 | *.la 8 | *.lai 9 | *.so 10 | *.dll 11 | *.dylib 12 | 13 | # Qt-es 14 | 15 | /.qmake.cache 16 | /.qmake.stash 17 | *.pro.user 18 | *.pro.user.* 19 | *.qbs.user 20 | *.qbs.user.* 21 | *.moc 22 | moc_*.h 23 | moc_*.cpp 24 | qrc_*.cpp 25 | ui_*.h 26 | Makefile* 27 | *build-* 28 | 29 | # QtCreator 30 | 31 | *.autosave 32 | 33 | #QtCtreator Qml 34 | *.qmlproject.user 35 | *.qmlproject.user.* 36 | 37 | build 38 | build2 39 | 40 | # KDE show hidden folder marker 41 | .directory 42 | 43 | 44 | # built tests executables 45 | test/tst_basic/tst_basic* 46 | test/tst_benckmark/tst_benchmark* 47 | test/tst_datatypes/tst_datatypes* 48 | test/tst_datetime/tst_datetime* 49 | test/tst_generators/target_wrapper.sh 50 | test/tst_generators/tst_generators* 51 | test/tst_json/tst_upgrades* 52 | test/tst_phrases/tst_phrases* 53 | test/tst_quuid/tst_uuid* 54 | test/tst_upgrades/tst_upgrades* 55 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.16) 2 | project(QInjection VERSION 1.0 LANGUAGES C CXX) 3 | 4 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 5 | 6 | # Set up AUTOMOC and some sensible defaults for runtime execution 7 | # When using Qt 6.3, you can replace the code block below with 8 | # qt_standard_project_setup() 9 | set(CMAKE_AUTOMOC ON) 10 | include(GNUInstallDirs) 11 | 12 | find_package(QT NAMES Qt5 Qt6 REQUIRED COMPONENTS Core) 13 | find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Gui Test) 14 | 15 | 16 | add_subdirectory(src) 17 | add_subdirectory(tests) 18 | -------------------------------------------------------------------------------- /QInjection.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = subdirs 2 | 3 | SUBDIRS += \ 4 | src \ 5 | tests 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Qt dependency injection lib 2 | 3 | QInjection is a dependency injection framework for Qt. It provides a way to automatically inject dependencies into classes, simplifying the process of creating and testing code. 4 | 5 | - QInjection is a dependency injection framework for Qt. 6 | - It has a simple and easy-to-use API. 7 | - It is lightweight and does not add much overhead to your code. 8 | - It can be used in any Qt project, regardless of the architecture or design pattern. 9 | - You just need to add objects to the pool and they will be automatically injected into your code. 10 | 11 | ## Quick start 12 | Imagine we have two classes named _MyClass1_ and _MyClass2_ that we use them regularly in our app. 13 | 14 | There are few ways to do that: 15 | 16 | 1. Create them everywhere needed! 17 | 2. Create an instance and pass it through object creation and function calls to different levels! 18 | 3. Use an _Dependency Injection_ framework. 19 | 20 | This repo that you are visiting is a simple way for the third solution 21 | 22 | This library has a mechanism to store an object into a pool and retrieve it wherever needed. Let's take a look at a simple example: 23 | 24 | First: adding objects to the dependency pool. In the main method we are adding an instance of _MyClass1_ and _MyClass2_ to the _Pool_. 25 | ```cpp 26 | #include "myclass.h" 27 | #include "dependencypool.h" 28 | 29 | #include 30 | 31 | MyClass *createMyClass() 32 | { 33 | auto o = new MyClass; 34 | // o->setSomeProperty(someValue); 35 | return o; 36 | } 37 | 38 | void foo(MyClass *object = QInjection::Inject) 39 | { 40 | // do something with object 41 | } 42 | 43 | int main(int argc, char *argv[]) 44 | { 45 | QCoreApplication a(argc, argv); 46 | 47 | QInjection::addSingleton(createMyClass); 48 | 49 | foo(); // <- Empty arguments; the object will be fetched from dependency injection pool 50 | return a.exec(); 51 | } 52 | ``` 53 | 54 | As you can see the object parameter of the method foo is not set; it will be fetched from the pool. Since MyClass is registered as a singleton, it will be the same object throughout the application code.. 55 | 56 | ## Api doc 57 | 58 | ### Singleton vs Scopped 59 | 60 | Singleton objects are the same for entire application lifetime, scopped objects are created on every request. 61 | 62 | ### Add an object to pool 63 | ```cpp 64 | template 65 | void addSingleton(); 66 | 67 | template 68 | void addSingleton(T *object); 69 | 70 | template 71 | void addSingleton(T*(*slot)() ); 72 | 73 | template 74 | void addSingleton(_Owner *owner, void (_Owner::*slot)(T *)); 75 | 76 | template 77 | void addScopped(T *(*slot)()) 78 | 79 | template 80 | void addScopped(_Owner *owner, void (_Owner::*slot)(T *)); 81 | ``` 82 | 83 | Examples: 84 | ```cpp 85 | 86 | MyAnotherClass *createMyAnotherClass() 87 | { 88 | auto o = new MyAnotherClass; 89 | // set some properties for object o 90 | return o; 91 | } 92 | 93 | int main(int argc, char *argv[]) 94 | { 95 | 96 | QCoreApplication a(argc, argv); 97 | 98 | auto obj = new MyClass; 99 | 100 | QInjection::addSingleton(obj); // pass object to dependency pool 101 | QInjection::addSingleton(createMyAnotherClass); // pass function pointer to dependency pool 102 | 103 | return a.exec(); 104 | } 105 | 106 | ``` 107 | 108 | ### Get object 109 | **There are some methods to get an object from the pool** 110 | 111 | The _QInjection::Pointer_ class is the main method of fetching object from the pool. It works like _QPointer_. It will delete it's content if the registration type is _scopped_. 112 | 113 | ```cpp 114 | void myMethod2() 115 | { 116 | QInjection::Pointer object; 117 | // This is where the object will be taken from the pool. 118 | // If it's registration type is of a scopped type, it'll be deleted after the end. 119 | } 120 | ``` 121 | 122 | Another method is using _QInjection::Inject_. It is Efficient if used in function parameters. In the example below you may pass an object of _MyClass_ type, if not it will be taken from the dependency injection pool. 123 | ```cpp 124 | void myMethod(Myclass *object = QInjection::Inject) 125 | { 126 | // You can pass a object of type MyClass to this method. If you don't, the object will be taken from QInjection pool 127 | } 128 | ``` 129 | 130 | ### Object change notify 131 | 132 | Sometimes we need to check when an object is being added or removed from the _DependencyInjection_ class. for that purpose, we have the _registerObjectNotify_ method in this class: 133 | 134 | ```cpp 135 | QInjection->add(); 136 | 137 | ... 138 | 139 | QInjection->registerObjectNotify(this, &MainWindow::interface_changed); 140 | ``` 141 | And in header we have a slot for this: 142 | 143 | ```cpp 144 | public slots: 145 | void interface_changed(Interface *project); 146 | ``` 147 | So when an object of type _Interface_ is going to be added or removed from DependencyInjection, this slot will be called. Note that when object gets removed from DependencyInjection, the parameter of this method will be _null_ptr_ 148 | 149 | Alternatively, this method can take a lambda: 150 | 151 | ```cpp 152 | dep->registerObjectNotify(this, [this](interface *interface) { 153 | if (interface) 154 | qDebug() << "Interface removved from pool"; 155 | else 156 | qDebug() << "Interface added to pool"; 157 | }); 158 | ``` 159 | -------------------------------------------------------------------------------- /src/.qmake2cmake/subdir-of: -------------------------------------------------------------------------------- 1 | /doc/dev/qt/VisualCodeEditor/3rdparty/QInjection/QInjection.pro 2 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.10) 2 | 3 | project(QInjection LANGUAGES CXX) 4 | 5 | # Try to find Qt6 first, fallback to Qt5 6 | find_package(Qt6 COMPONENTS Core QUIET) 7 | if(Qt6_FOUND) 8 | set(QT_VERSION_MAJOR 6) 9 | find_package(Qt6 REQUIRED COMPONENTS Core) 10 | set(QT_CORE_TARGET Qt6::Core) 11 | else() 12 | set(QT_VERSION_MAJOR 5) 13 | find_package(Qt5 REQUIRED COMPONENTS Core) 14 | set(QT_CORE_TARGET Qt5::Core) 15 | endif() 16 | 17 | # Setup automoc/uic/rcc for Qt5 18 | if(QT_VERSION_MAJOR EQUAL 5) 19 | set(CMAKE_AUTOMOC ON) 20 | set(CMAKE_AUTOUIC ON) 21 | set(CMAKE_AUTORCC ON) 22 | endif() 23 | 24 | set(QInjection_Source 25 | dep_global.h 26 | dependencycreator.cpp dependencycreator.h 27 | dependencyinjector.cpp dependencyinjector.h 28 | dependencypointer.cpp dependencypointer.h 29 | dependencypool.cpp dependencypool.h 30 | ) 31 | 32 | if(QT_VERSION_MAJOR EQUAL 6) 33 | qt_add_library(QInjection ${QInjection_Source}) 34 | qt_add_library(QInjectionStatic STATIC ${QInjection_Source}) 35 | else() 36 | add_library(QInjection ${QInjection_Source}) 37 | add_library(QInjectionStatic STATIC ${QInjection_Source}) 38 | endif() 39 | 40 | target_compile_definitions(QInjection PUBLIC 41 | QT_DEPRECATED_WARNINGS 42 | SRC_LIBRARY 43 | ) 44 | target_compile_definitions(QInjectionStatic PUBLIC 45 | QT_DEPRECATED_WARNINGS 46 | SRC_LIBRARY 47 | ) 48 | 49 | target_link_libraries(QInjection PUBLIC ${QT_CORE_TARGET}) 50 | target_link_libraries(QInjectionStatic PUBLIC ${QT_CORE_TARGET}) 51 | 52 | target_include_directories(QInjection PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 53 | target_include_directories(QInjectionStatic PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 54 | 55 | install(TARGETS QInjection 56 | LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} 57 | FRAMEWORK DESTINATION ${CMAKE_INSTALL_LIBDIR} 58 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 59 | ) 60 | -------------------------------------------------------------------------------- /src/dep_global.h: -------------------------------------------------------------------------------- 1 | #ifndef SRC_GLOBAL_H 2 | #define SRC_GLOBAL_H 3 | 4 | #include 5 | 6 | #if defined(SRC_LIBRARY) 7 | # define SRC_EXPORT Q_DECL_EXPORT 8 | #else 9 | # define SRC_EXPORT Q_DECL_IMPORT 10 | #endif 11 | 12 | #endif // SRC_GLOBAL_H 13 | -------------------------------------------------------------------------------- /src/dependencycreator.cpp: -------------------------------------------------------------------------------- 1 | #include "dependencycreator.h" 2 | 3 | -------------------------------------------------------------------------------- /src/dependencycreator.h: -------------------------------------------------------------------------------- 1 | #ifndef DEPENDENCYCREATOR_H 2 | #define DEPENDENCYCREATOR_H 3 | 4 | #include 5 | #include 6 | #define CLASS_NAME(T) T::staticMetaObject.className() 7 | 8 | namespace QInjection { 9 | 10 | enum class CreatorType { 11 | Unknown, 12 | Singelton, 13 | Scopped 14 | }; 15 | 16 | struct CreatorBase 17 | { 18 | CreatorType _type; 19 | QString _key; 20 | QObject *_object{nullptr}; 21 | CreatorBase(CreatorType type, const QString &key); 22 | virtual QObject *create() = 0; 23 | }; 24 | 25 | inline CreatorBase::CreatorBase(CreatorType type, const QString &key) 26 | : _type(type) 27 | , _key(key) 28 | {} 29 | 30 | template 31 | struct FunctionCreator : CreatorBase 32 | { 33 | T *(*_creatorFunction)(); 34 | 35 | FunctionCreator (CreatorType type, T *(*creatorFunction)()); 36 | 37 | QObject *create() override; 38 | }; 39 | 40 | template 41 | struct SimpleCreator : CreatorBase 42 | { 43 | T *_object; 44 | 45 | SimpleCreator (CreatorType type, T *object); 46 | 47 | QObject *create() override; 48 | }; 49 | 50 | template 51 | struct OnceCreator : CreatorBase 52 | { 53 | T *_object{nullptr}; 54 | 55 | OnceCreator (CreatorType type); 56 | 57 | QObject *create() override; 58 | }; 59 | 60 | template 61 | Q_OUTOFLINE_TEMPLATE OnceCreator::OnceCreator(CreatorType type) 62 | : CreatorBase(type, CLASS_NAME(T)) 63 | { 64 | 65 | } 66 | 67 | template 68 | Q_OUTOFLINE_TEMPLATE QObject *OnceCreator::create() 69 | { 70 | if (!_object) 71 | _object = new T; 72 | return _object; 73 | } 74 | 75 | template 76 | Q_OUTOFLINE_TEMPLATE SimpleCreator::SimpleCreator(CreatorType type, T *object) 77 | : CreatorBase(type, CLASS_NAME(T)) 78 | , _object(object) 79 | { 80 | 81 | } 82 | 83 | template 84 | Q_OUTOFLINE_TEMPLATE QObject *SimpleCreator::create() 85 | { 86 | return _object; 87 | } 88 | 89 | template 90 | Q_OUTOFLINE_TEMPLATE FunctionCreator::FunctionCreator(CreatorType type, T *(*creatorFunction)()) 91 | : CreatorBase(type, CLASS_NAME(T)) 92 | , _creatorFunction(creatorFunction) 93 | {} 94 | 95 | template 96 | Q_OUTOFLINE_TEMPLATE QObject *FunctionCreator::create() 97 | { 98 | return _creatorFunction(); 99 | } 100 | 101 | template 102 | struct ClassFunctionCreator : CreatorBase 103 | { 104 | T *(OWNER::*_creatorFunction)(); 105 | OWNER *_owner; 106 | 107 | ClassFunctionCreator (CreatorType type, OWNER *owner, T *(OWNER::*creatorFunction)()); 108 | 109 | QObject *create() override; 110 | }; 111 | 112 | template 113 | Q_OUTOFLINE_TEMPLATE ClassFunctionCreator::ClassFunctionCreator( 114 | CreatorType type, OWNER *owner, T *(OWNER::*creatorFunction)()) 115 | : CreatorBase(type, CLASS_NAME(T)), _creatorFunction(creatorFunction), _owner(owner) 116 | { 117 | } 118 | 119 | template 120 | Q_OUTOFLINE_TEMPLATE QObject *ClassFunctionCreator::create() 121 | { 122 | return (_owner->*_creatorFunction)(); 123 | } 124 | 125 | 126 | struct SignalBase 127 | { 128 | QString _key; 129 | void check(const QString &key, QObject *obj) 130 | { 131 | if (key == _key) 132 | call(obj); 133 | } 134 | virtual void call(QObject *obj) { 135 | Q_UNUSED(obj) 136 | } 137 | }; 138 | 139 | template 140 | struct SignalPointer : SignalBase 141 | { 142 | R *reciver; 143 | void (R::*slot)(T *); 144 | 145 | void call(QObject *obj) override { 146 | if (obj) 147 | (reciver->*slot)(qobject_cast(obj)); 148 | else 149 | (reciver->*slot)(nullptr); 150 | } 151 | }; 152 | 153 | template 154 | struct SignalPointerWithoutParam : SignalBase { 155 | R *reciver; 156 | void (R::*slot)(); 157 | 158 | void call(QObject *obj) override 159 | { 160 | Q_UNUSED(obj) 161 | (reciver->*slot)(); 162 | } 163 | }; 164 | 165 | template 166 | struct SignalPointerFunc : SignalBase { 167 | std::function _cb; 168 | 169 | void call(QObject *obj) override 170 | { 171 | if (obj) 172 | _cb(qobject_cast(obj)); 173 | else 174 | _cb(nullptr); 175 | } 176 | }; 177 | 178 | } // namespace QInjection 179 | 180 | #endif // DEPENDENCYCREATOR_H 181 | -------------------------------------------------------------------------------- /src/dependencyinjector.cpp: -------------------------------------------------------------------------------- 1 | #include "dependencyinjector.h" 2 | 3 | namespace QInjection { 4 | 5 | Injecter Inject; 6 | 7 | Injecter::Injecter() : _key{nullptr} {} 8 | 9 | Injecter::Injecter(const char *key) : _key(key) {} 10 | 11 | } // namespace QInjection 12 | -------------------------------------------------------------------------------- /src/dependencyinjector.h: -------------------------------------------------------------------------------- 1 | #ifndef DEPENDENCYINJECTOR_H 2 | #define DEPENDENCYINJECTOR_H 3 | 4 | #include "dependencypool.h" 5 | 6 | namespace QInjection { 7 | 8 | class Injecter 9 | { 10 | const char *_key{nullptr}; 11 | 12 | public: 13 | Injecter(); 14 | Injecter(const char *key); 15 | 16 | Injecter(const Injecter &) = delete; 17 | Injecter(Injecter &&) = delete; 18 | 19 | template 20 | operator T *() 21 | { 22 | T *tmp = nullptr; 23 | if (_key) 24 | tmp = qobject_cast(Private::create(_key)); 25 | else 26 | tmp = create(); 27 | 28 | if (tmp && Private::typeForKey(CLASS_NAME(T)) == CreatorType::Scopped) 29 | tmp->deleteLater(); 30 | return tmp; 31 | } 32 | }; 33 | 34 | extern Injecter Inject; 35 | } // namespace QInjection 36 | 37 | #endif // DEPENDENCYINJECTOR_H 38 | -------------------------------------------------------------------------------- /src/dependencypointer.cpp: -------------------------------------------------------------------------------- 1 | #include "dependencypointer.h" 2 | 3 | /*! 4 | * \class DependencyPointer 5 | 6 | */ 7 | -------------------------------------------------------------------------------- /src/dependencypointer.h: -------------------------------------------------------------------------------- 1 | #ifndef DEPENDENCYPOINTER_H 2 | #define DEPENDENCYPOINTER_H 3 | 4 | #include "dependencypool.h" 5 | 6 | #include 7 | #include 8 | 9 | namespace QInjection { 10 | 11 | template 12 | class Pointer : public QObject{ 13 | Q_STATIC_ASSERT_X(!std::is_pointer::value, "QPointer's template type must not be a pointer type"); 14 | 15 | T *_data; 16 | bool _deleteOnExit{false}; 17 | 18 | public: 19 | Pointer(); 20 | ~Pointer(); 21 | 22 | T *data() const; 23 | T *operator->() const; 24 | T &operator*() const; 25 | inline operator T *() const 26 | { 27 | return data(); 28 | } 29 | 30 | inline bool isNull() const 31 | { 32 | return _data == nullptr; 33 | } 34 | 35 | inline void clear() 36 | { 37 | _data = nullptr; 38 | } 39 | }; 40 | 41 | template 42 | Q_OUTOFLINE_TEMPLATE Pointer::Pointer() : _data(create()) 43 | { 44 | auto t = Private::typeForKey(CLASS_NAME(T)); 45 | _deleteOnExit = t == CreatorType::Scopped; 46 | registerObjectNotify(this, [this](T *t) { 47 | _data = t; 48 | }); 49 | } 50 | 51 | template 52 | Q_OUTOFLINE_TEMPLATE Pointer::~Pointer() 53 | { 54 | if (_deleteOnExit && _data) 55 | Private::deleteObject(static_cast(_data)); 56 | } 57 | 58 | template 59 | Q_OUTOFLINE_TEMPLATE T *Pointer::data() const 60 | { 61 | return _data; 62 | } 63 | 64 | template 65 | Q_OUTOFLINE_TEMPLATE T *Pointer::operator->() const 66 | { 67 | return data(); 68 | } 69 | 70 | template 71 | Q_OUTOFLINE_TEMPLATE T &Pointer::operator*() const 72 | { 73 | return *data(); 74 | } 75 | 76 | } 77 | 78 | template 79 | Q_DECLARE_TYPEINFO_BODY(QInjection::Pointer, Q_MOVABLE_TYPE); 80 | 81 | template 82 | inline bool operator==(const T *o, const QInjection::Pointer &p) 83 | { 84 | return o == p.operator->(); 85 | } 86 | 87 | template 88 | inline bool operator==(const QInjection::Pointer &p, const T *o) 89 | { 90 | return p.operator->() == o; 91 | } 92 | 93 | template 94 | inline bool operator==(T *o, const QInjection::Pointer &p) 95 | { 96 | return o == p.operator->(); 97 | } 98 | 99 | template 100 | inline bool operator==(const QInjection::Pointer &p, T *o) 101 | { 102 | return p.operator->() == o; 103 | } 104 | 105 | template 106 | inline bool operator==(const QInjection::Pointer &p1, 107 | const QInjection::Pointer &p2) 108 | { 109 | return p1.operator->() == p2.operator->(); 110 | } 111 | 112 | template 113 | inline bool operator!=(const T *o, const QInjection::Pointer &p) 114 | { 115 | return o != p.operator->(); 116 | } 117 | 118 | template 119 | inline bool operator!=(const QInjection::Pointer &p, const T *o) 120 | { 121 | return p.operator->() != o; 122 | } 123 | 124 | template 125 | inline bool operator!=(T *o, const QInjection::Pointer &p) 126 | { 127 | return o != p.operator->(); 128 | } 129 | 130 | template 131 | inline bool operator!=(const QInjection::Pointer &p, T *o) 132 | { 133 | return p.operator->() != o; 134 | } 135 | 136 | template 137 | inline bool operator!=(const QInjection::Pointer &p1, 138 | const QInjection::Pointer &p2) 139 | { 140 | return p1.operator->() != p2.operator->(); 141 | } 142 | 143 | 144 | #ifndef QINJECTION_BC 145 | namespace Dependency { 146 | template 147 | class Pointr : public QInjection::Pointer 148 | {}; 149 | 150 | } 151 | #endif 152 | #endif // DEPENDENCYPOINTER_H 153 | -------------------------------------------------------------------------------- /src/dependencypool.cpp: -------------------------------------------------------------------------------- 1 | #include "dependencypool.h" 2 | 3 | #include 4 | #include 5 | 6 | namespace QInjection { 7 | 8 | struct Data { 9 | QMap creators; 10 | QList notifySignals; 11 | }; 12 | Q_GLOBAL_STATIC(Data, d); 13 | 14 | namespace Private { 15 | 16 | QObject *create(const QString &key) 17 | { 18 | if (!d->creators.contains(key)) 19 | return nullptr; 20 | 21 | auto creator = d->creators.value(key); 22 | 23 | switch (creator->_type) { 24 | case CreatorType::Unknown: 25 | return nullptr; 26 | 27 | case CreatorType::Scopped: 28 | return creator->create(); 29 | 30 | case CreatorType::Singelton: { 31 | if (creator->_object) 32 | return creator->_object; 33 | 34 | creator->_object = creator->create(); 35 | return creator->_object; 36 | } 37 | } 38 | 39 | Q_UNREACHABLE(); 40 | 41 | return nullptr; 42 | } 43 | bool remove(const QString &name) 44 | { 45 | if (!d->creators.contains(name)) 46 | return false; 47 | 48 | auto creator = d->creators.value(name); 49 | if (creator->_type == CreatorType::Singelton && creator->_object) 50 | creator->_object->deleteLater(); 51 | return d->creators.remove(name) > 0; 52 | } 53 | 54 | bool contains(const QString &key) 55 | { 56 | return d->creators.contains(key); 57 | } 58 | 59 | void addCreator(const QString &key, CreatorBase *creator) 60 | { 61 | if (d->creators.contains(key)) { 62 | qWarning("Dependency pool already has a %s key", key.toLatin1().data()); 63 | return; 64 | } 65 | d->creators.insert(key, creator); 66 | } 67 | 68 | void addSignel(SignalBase *signal) 69 | { 70 | d->notifySignals.append(signal); 71 | } 72 | 73 | void removeSignel(SignalBase *signal) 74 | { 75 | d->notifySignals.removeOne(signal); 76 | } 77 | 78 | int callSlots(QObject *o, bool sendNull) 79 | { 80 | QString key{o->metaObject()->className()}; 81 | int ret{0}; 82 | 83 | for (auto &s : d->notifySignals) 84 | if (s->_key == key) { 85 | s->call(sendNull ? nullptr : o); 86 | ret++; 87 | } 88 | return ret; 89 | } 90 | 91 | CreatorType typeForKey(const QString &key) 92 | { 93 | if (!d->creators.contains(key)) 94 | return CreatorType::Unknown; 95 | return d->creators.value(key)->_type; 96 | } 97 | 98 | void deleteObject(QObject *obj) 99 | { 100 | obj->deleteLater(); 101 | } 102 | 103 | } // namespace Impl 104 | 105 | } // namespace QInjection 106 | -------------------------------------------------------------------------------- /src/dependencypool.h: -------------------------------------------------------------------------------- 1 | #ifndef Pool_H 2 | #define Pool_H 3 | 4 | #include 5 | #include 6 | #include "dependencycreator.h" 7 | 8 | #define dep ::QInjection 9 | #define di_new(Type, ...) ::QInjection::create() 10 | #define di_get(type) ::QInjection::get() 11 | #define di_add(type) ::QInjection::add() 12 | #define CLASS_NAME(T) T::staticMetaObject.className() 13 | 14 | namespace QInjection { 15 | 16 | namespace Private { 17 | 18 | QObject *create(const QString &key); 19 | bool remove(const QString &name); 20 | bool contains(const QString &key); 21 | 22 | void addCreator(const QString &key, CreatorBase *creator); 23 | void addSignel(SignalBase *signal); 24 | void removeSignel(SignalBase *signal); 25 | int callSlots(QObject *o, bool sendNull = false); 26 | CreatorType typeForKey(const QString &key); 27 | void deleteObject(QObject *obj); 28 | 29 | } // namespace Impl 30 | 31 | #ifdef QOIJECTION_OLD 32 | QObject *create(const QString &key); 33 | bool remove(const QString &name); 34 | bool contains(const QString &key); 35 | #endif 36 | 37 | template 38 | Q_OUTOFLINE_TEMPLATE bool remove(){ 39 | return Private::remove(CLASS_NAME(T)); 40 | } 41 | 42 | template 43 | Q_OUTOFLINE_TEMPLATE T *create() 44 | { 45 | return qobject_cast(Private::create(CLASS_NAME(T))); 46 | } 47 | 48 | // Add Objects 49 | template 50 | Q_OUTOFLINE_TEMPLATE void addSingleton() 51 | { 52 | auto creator = new OnceCreator(CreatorType::Singelton); 53 | Private::addCreator(CLASS_NAME(T), creator); 54 | } 55 | 56 | template 57 | Q_OUTOFLINE_TEMPLATE void addSingleton(T *object) { 58 | auto creator = new SimpleCreator(CreatorType::Singelton, object); 59 | Private::addCreator(CLASS_NAME(T), creator); 60 | } 61 | 62 | template 63 | Q_OUTOFLINE_TEMPLATE void addSingleton(T*(*slot)() ) { 64 | auto creator = new FunctionCreator(CreatorType::Singelton, slot); 65 | Private::addCreator(CLASS_NAME(T), creator); 66 | } 67 | 68 | template 69 | Q_OUTOFLINE_TEMPLATE void addSingleton(_Owner *owner, void (_Owner::*slot)(T *)) 70 | { 71 | auto creator = new ClassFunctionCreator<_Owner, T>(CreatorType::Singelton, owner, slot); 72 | Private::addCreator(CLASS_NAME(T), creator); 73 | } 74 | 75 | template 76 | Q_OUTOFLINE_TEMPLATE void addScopped(T *(*slot)()) 77 | { 78 | auto creator = new FunctionCreator(CreatorType::Scopped, slot); 79 | Private::addCreator(CLASS_NAME(T), creator); 80 | } 81 | 82 | template 83 | Q_OUTOFLINE_TEMPLATE void addScopped(_Owner *owner, void (_Owner::*slot)(T *)) 84 | { 85 | auto creator = new ClassFunctionCreator<_Owner, T>(CreatorType::Scopped, owner, slot); 86 | Private::addCreator(CLASS_NAME(T), creator); 87 | } 88 | 89 | template 90 | Q_OUTOFLINE_TEMPLATE void registerObjectNotify( 91 | R *reciver, 92 | void(R::*slot)(T*)) 93 | { 94 | QString key = CLASS_NAME(T); 95 | auto s = new SignalPointer(); 96 | s->_key = key; 97 | s->slot = slot; 98 | s->reciver = reciver; 99 | Private::addSignel(s); 100 | 101 | QObject::connect(reciver, &QObject::destroyed, [s](QObject * = nullptr) { 102 | Private::removeSignel(s); 103 | }); 104 | } 105 | 106 | template 107 | Q_OUTOFLINE_TEMPLATE void registerObjectNotify( 108 | R *reciver, 109 | void(R::*slot)()) 110 | { 111 | QString key = CLASS_NAME(T); 112 | auto s = new SignalPointerWithoutParam(); 113 | s->_key = key; 114 | s->slot = slot; 115 | s->reciver = reciver; 116 | Private::addSignel(s); 117 | 118 | QObject::connect(reciver, &QObject::destroyed, [s](QObject * = nullptr) { 119 | Private::removeSignel(s); 120 | }); 121 | } 122 | 123 | template 124 | Q_OUTOFLINE_TEMPLATE void registerObjectNotify( 125 | R *reciver, 126 | std::function cb) 127 | { 128 | QString key = CLASS_NAME(T); 129 | auto s = new SignalPointerFunc(); 130 | s->_key = key; 131 | s->_cb = cb; 132 | Private::addSignel(s); 133 | 134 | QObject::connect(reciver, &QObject::destroyed, [s](QObject * = nullptr) { 135 | Private::removeSignel(s); 136 | }); 137 | } 138 | 139 | } 140 | 141 | #endif // Pool_H 142 | -------------------------------------------------------------------------------- /src/src.pri: -------------------------------------------------------------------------------- 1 | INCLUDEPATH += $$PWD 2 | 3 | DEFINES += QINJECTION_LIB 4 | 5 | SOURCES += \ 6 | $$PWD/dependencycreator.cpp \ 7 | $$PWD/dependencyinjector.cpp \ 8 | $$PWD/dependencypointer.cpp \ 9 | $$PWD/dependencypool.cpp 10 | 11 | HEADERS += \ 12 | $$PWD/dep_global.h \ 13 | $$PWD/dependencycreator.h \ 14 | $$PWD/dependencyinjector.h \ 15 | $$PWD/dependencypointer.h \ 16 | $$PWD/dependencypool.h \ 17 | $$PWD/dependencypool_p.h 18 | -------------------------------------------------------------------------------- /src/src.pro: -------------------------------------------------------------------------------- 1 | QT -= gui 2 | 3 | TEMPLATE = lib 4 | DEFINES += SRC_LIBRARY 5 | 6 | CONFIG += c++11 7 | 8 | # The following define makes your compiler emit warnings if you use 9 | # any Qt feature that has been marked deprecated (the exact warnings 10 | # depend on your compiler). Please consult the documentation of the 11 | # deprecated API in order to know how to port your code away from it. 12 | DEFINES += QT_DEPRECATED_WARNINGS 13 | 14 | # You can also make your code fail to compile if it uses deprecated APIs. 15 | # In order to do so, uncomment the following line. 16 | # You can also select to disable deprecated APIs only up to a certain version of Qt. 17 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 18 | 19 | SOURCES += \ 20 | dependencycreator.cpp \ 21 | dependencyinjector.cpp \ 22 | dependencypointer.cpp \ 23 | dependencypool.cpp 24 | 25 | HEADERS += \ 26 | dep_global.h \ 27 | dependencycreator.h \ 28 | dependencyinjector.h \ 29 | dependencypointer.h \ 30 | dependencypool.h 31 | 32 | # Default rules for deployment. 33 | unix { 34 | target.path = /usr/lib 35 | } 36 | !isEmpty(target.path): INSTALLS += target 37 | -------------------------------------------------------------------------------- /tests/.qmake2cmake/subdir-of: -------------------------------------------------------------------------------- 1 | /doc/dev/qt/VisualCodeEditor/3rdparty/QInjection/QInjection.pro 2 | -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.16) 2 | project(tests VERSION 1.0 LANGUAGES C CXX) 3 | 4 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 5 | 6 | # Set up AUTOMOC and some sensible defaults for runtime execution 7 | # When using Qt 6.3, you can replace the code block below with 8 | # qt_standard_project_setup() 9 | set(CMAKE_AUTOMOC ON) 10 | include(GNUInstallDirs) 11 | 12 | find_package(QT NAMES Qt5 Qt6 REQUIRED COMPONENTS Core) 13 | 14 | 15 | add_subdirectory(NewAPI) 16 | add_subdirectory(auto_create) 17 | add_subdirectory(main) 18 | -------------------------------------------------------------------------------- /tests/NewAPI/.qmake2cmake/subdir-of: -------------------------------------------------------------------------------- 1 | /doc/dev/qt/VisualCodeEditor/3rdparty/QInjection/tests/tests.pro 2 | -------------------------------------------------------------------------------- /tests/NewAPI/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | qt_add_executable( 2 | NewAPI 3 | ../common/adder.cpp ../common/adder.h 4 | tst_newapi.cpp 5 | ) 6 | target_include_directories(NewAPI PRIVATE 7 | ../../src 8 | ../common 9 | ) 10 | 11 | target_compile_definitions(NewAPI PRIVATE 12 | QINJECTION_LIB 13 | ) 14 | 15 | target_link_libraries(NewAPI PRIVATE 16 | QInjectionStatic 17 | Qt::Core 18 | Qt::Test 19 | ) 20 | 21 | install(TARGETS NewAPI 22 | BUNDLE DESTINATION . 23 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 24 | ) 25 | 26 | # Consider using qt_generate_deploy_app_script() for app deployment if 27 | # the project can use Qt 6.3. In that case rerun qmake2cmake with 28 | # --min-qt-version=6.3. 29 | -------------------------------------------------------------------------------- /tests/NewAPI/NewAPI.pro: -------------------------------------------------------------------------------- 1 | QT += testlib 2 | QT -= gui 3 | 4 | CONFIG += qt console warn_on depend_includepath testcase 5 | CONFIG -= app_bundle 6 | 7 | TEMPLATE = app 8 | 9 | SOURCES += tst_newapi.cpp \ 10 | ../common/adder.cpp 11 | 12 | include(../../src/src.pri) 13 | 14 | INCLUDEPATH += ../common/ 15 | 16 | HEADERS += \ 17 | ../common/adder.h 18 | -------------------------------------------------------------------------------- /tests/NewAPI/tst_newapi.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "adder.h" 4 | #include 5 | #include 6 | 7 | Adder *createAdder() 8 | { 9 | return new Adder; 10 | } 11 | 12 | class NewAPI : public QObject 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | NewAPI(); 18 | ~NewAPI(); 19 | 20 | private slots: 21 | void test_case1(); 22 | void test_bc(); 23 | }; 24 | 25 | NewAPI::NewAPI() 26 | { 27 | QInjection::addSingleton(createAdder); 28 | } 29 | 30 | NewAPI::~NewAPI() {} 31 | 32 | void NewAPI::test_case1() 33 | { 34 | QInjection::Pointer adder; 35 | QCOMPARE(adder->add(1, 2), 3); 36 | } 37 | 38 | void NewAPI::test_bc() 39 | { 40 | Dependency::Pointr adder; 41 | QCOMPARE(adder->add(1, 2), 3); 42 | } 43 | 44 | QTEST_APPLESS_MAIN(NewAPI) 45 | 46 | #include "tst_newapi.moc" 47 | -------------------------------------------------------------------------------- /tests/auto_create/.qmake2cmake/subdir-of: -------------------------------------------------------------------------------- 1 | /doc/dev/qt/VisualCodeEditor/3rdparty/QInjection/tests/tests.pro 2 | -------------------------------------------------------------------------------- /tests/auto_create/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | qt_add_executable( 2 | auto_create 3 | ../common/constholder.cpp ../common/constholder.h 4 | tst_create.cpp 5 | ) 6 | target_include_directories(auto_create PRIVATE 7 | ../../src 8 | ../common 9 | ) 10 | 11 | target_compile_definitions(auto_create PRIVATE 12 | QINJECTION_LIB 13 | ) 14 | 15 | target_link_libraries(auto_create PRIVATE 16 | QInjectionStatic 17 | Qt::Core 18 | Qt::Test 19 | ) 20 | 21 | install(TARGETS auto_create 22 | BUNDLE DESTINATION . 23 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 24 | ) 25 | 26 | # Consider using qt_generate_deploy_app_script() for app deployment if 27 | # the project can use Qt 6.3. In that case rerun qmake2cmake with 28 | # --min-qt-version=6.3. 29 | -------------------------------------------------------------------------------- /tests/auto_create/auto_create.pro: -------------------------------------------------------------------------------- 1 | QT += testlib 2 | QT -= gui 3 | 4 | CONFIG += qt console warn_on depend_includepath testcase cpp14 5 | CONFIG -= app_bundle 6 | 7 | TEMPLATE = app 8 | 9 | SOURCES += tst_create.cpp \ 10 | ../common/constholder.cpp 11 | 12 | HEADERS += \ 13 | ../common/constholder.h 14 | 15 | INCLUDEPATH += ../common/ 16 | 17 | include(../../src/src.pri) 18 | -------------------------------------------------------------------------------- /tests/auto_create/tst_create.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "constholder.h" 4 | #include 5 | #include 6 | #include 7 | 8 | constexpr int _value = 123; 9 | 10 | class tst_create : public QObject 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | tst_create(); 16 | ~tst_create(); 17 | 18 | private slots: 19 | void test_inject(); 20 | void test_create_on_param(ConstHolder *holder); 21 | void test_pointer(); 22 | void test_creatot_params(); 23 | }; 24 | 25 | ConstHolder *createConstHolder() 26 | { 27 | auto c = new ConstHolder; 28 | c->setValue(_value); 29 | return c; 30 | } 31 | tst_create::tst_create() 32 | { 33 | QInjection::addSingleton(createConstHolder); 34 | } 35 | 36 | tst_create::~tst_create() 37 | { 38 | 39 | } 40 | 41 | void tst_create::test_inject() 42 | { 43 | ConstHolder *holder = QInjection::Inject; 44 | // QInjection::Pointer holder; 45 | QCOMPARE(holder->value(), _value); 46 | } 47 | 48 | void tst_create::test_create_on_param(ConstHolder *holder = QInjection::Inject) 49 | { 50 | QCOMPARE(holder->value(), _value); 51 | } 52 | 53 | void tst_create::test_pointer() 54 | { 55 | QInjection::Pointer holder; 56 | QCOMPARE(holder->value(), _value); 57 | } 58 | 59 | void tst_create::test_creatot_params() 60 | { 61 | constexpr int n = 456; 62 | QInjection::remove(); 63 | // dep->registerCreator(n); 64 | // ConstHolder *holder = QInjection::Inject; 65 | // QInjection::Pointer holder; 66 | // QCOMPARE(holder->value(), n); 67 | } 68 | 69 | QTEST_APPLESS_MAIN(tst_create) 70 | 71 | #include "tst_create.moc" 72 | -------------------------------------------------------------------------------- /tests/common/adder.cpp: -------------------------------------------------------------------------------- 1 | #include "adder.h" 2 | 3 | Adder::Adder(QObject *parent) : QObject(parent) 4 | { 5 | 6 | } 7 | 8 | int Adder::add(int n1, int n2) const 9 | { 10 | return n1 + n2; 11 | } 12 | -------------------------------------------------------------------------------- /tests/common/adder.h: -------------------------------------------------------------------------------- 1 | #ifndef ADDER_H 2 | #define ADDER_H 3 | 4 | #include 5 | 6 | class Adder : public QObject 7 | { 8 | Q_OBJECT 9 | public: 10 | explicit Adder(QObject *parent = nullptr); 11 | 12 | int add(int n1, int n2) const; 13 | signals: 14 | 15 | }; 16 | 17 | #endif // ADDER_H 18 | -------------------------------------------------------------------------------- /tests/common/constholder.cpp: -------------------------------------------------------------------------------- 1 | #include "constholder.h" 2 | 3 | int ConstHolder::value() const 4 | { 5 | return _value; 6 | } 7 | 8 | void ConstHolder::setValue(int value) 9 | { 10 | _value = value; 11 | } 12 | 13 | ConstHolder::ConstHolder(QObject *parent) : QObject(parent) 14 | { 15 | 16 | } 17 | 18 | ConstHolder::ConstHolder(int n, QObject *parent) : QObject(parent), _value{n} 19 | { 20 | 21 | } 22 | -------------------------------------------------------------------------------- /tests/common/constholder.h: -------------------------------------------------------------------------------- 1 | #ifndef CONSTHOLDER_H 2 | #define CONSTHOLDER_H 3 | 4 | #include 5 | 6 | class ConstHolder : public QObject 7 | { 8 | Q_OBJECT 9 | int _value; 10 | 11 | public: 12 | explicit ConstHolder(QObject *parent = nullptr); 13 | explicit ConstHolder(int n, QObject *parent = nullptr); 14 | 15 | int value() const; 16 | void setValue(int value); 17 | 18 | signals: 19 | 20 | }; 21 | 22 | #endif // CONSTHOLDER_H 23 | -------------------------------------------------------------------------------- /tests/main/.qmake2cmake/subdir-of: -------------------------------------------------------------------------------- 1 | /doc/dev/qt/VisualCodeEditor/3rdparty/QInjection/tests/tests.pro 2 | -------------------------------------------------------------------------------- /tests/main/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | qt_add_executable( 2 | tst_main WIN32 MACOSX_BUNDLE 3 | ../common/adder.cpp ../common/adder.h 4 | ../common/constholder.cpp ../common/constholder.h 5 | lifetimereporter.cpp lifetimereporter.h 6 | tst_main.cpp tst_main.h 7 | ) 8 | target_include_directories(tst_main PRIVATE 9 | ../../src 10 | ../common 11 | ) 12 | 13 | target_compile_definitions(tst_main PRIVATE 14 | QINJECTION_LIB 15 | ) 16 | 17 | target_link_libraries(tst_main PRIVATE 18 | QInjectionStatic 19 | Qt::Core 20 | Qt::Test 21 | ) 22 | 23 | install(TARGETS tst_main 24 | BUNDLE DESTINATION . 25 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 26 | ) 27 | 28 | # Consider using qt_generate_deploy_app_script() for app deployment if 29 | # the project can use Qt 6.3. In that case rerun qmake2cmake with 30 | # --min-qt-version=6.3. 31 | -------------------------------------------------------------------------------- /tests/main/lifetimereporter.cpp: -------------------------------------------------------------------------------- 1 | #include "lifetimereporter.h" 2 | 3 | #include 4 | LifeTimeReporter::LifeTimeReporter(bool *value, QObject *parent) 5 | : QObject{parent}, _v(value) 6 | { 7 | *_v = true; 8 | } 9 | 10 | LifeTimeReporter::~LifeTimeReporter() 11 | { 12 | *_v = false; 13 | qDebug() << "destroyed"; 14 | } 15 | -------------------------------------------------------------------------------- /tests/main/lifetimereporter.h: -------------------------------------------------------------------------------- 1 | #ifndef LIFETIMEREPORTER_H 2 | #define LIFETIMEREPORTER_H 3 | 4 | #include 5 | 6 | class LifeTimeReporter : public QObject 7 | { 8 | Q_OBJECT 9 | bool *_v; 10 | 11 | public: 12 | explicit LifeTimeReporter(bool *value, QObject *parent = nullptr); 13 | ~LifeTimeReporter(); 14 | 15 | signals: 16 | }; 17 | 18 | #endif // LIFETIMEREPORTER_H 19 | -------------------------------------------------------------------------------- /tests/main/main.pro: -------------------------------------------------------------------------------- 1 | QT += testlib 2 | QT -= gui 3 | 4 | TEMPLATE = app 5 | TARGET = tst_main 6 | 7 | #CONFIG += qt console warn_on depend_includepath testcase 8 | #CONFIG -= app_bundle 9 | 10 | TEMPLATE = app 11 | 12 | SOURCES += \ 13 | ../common/adder.cpp \ 14 | ../common/constholder.cpp \ 15 | lifetimereporter.cpp \ 16 | tst_main.cpp 17 | 18 | HEADERS += \ 19 | ../common/adder.h \ 20 | ../common/constholder.h \ 21 | lifetimereporter.h \ 22 | tst_main.h 23 | 24 | INCLUDEPATH += ../common/ 25 | include(../../src/src.pri) 26 | -------------------------------------------------------------------------------- /tests/main/tst_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include "tst_main.h" 6 | #include "dependencypool.h" 7 | #include "dependencypointer.h" 8 | #include "dependencyinjector.h" 9 | #include "adder.h" 10 | #include "constholder.h" 11 | #include "lifetimereporter.h" 12 | 13 | bool lifeTime; 14 | 15 | LifeTimeReporter *createLifeTimeReporter() { 16 | return new LifeTimeReporter(&lifeTime); 17 | } 18 | 19 | ConstHolder *createRandomNumberHolder() { 20 | qDebug() << "Creating const helper"; 21 | auto o = new ConstHolder; 22 | static int index = 1; 23 | o->setValue(index); 24 | index++; 25 | return o; 26 | } 27 | 28 | MainTest::MainTest(QObject *parent) : QObject(parent) { 29 | QInjection::addScopped(createRandomNumberHolder); 30 | } 31 | 32 | void MainTest::initTestCase() 33 | { 34 | qDebug() << Q_FUNC_INFO; 35 | QInjection::addSingleton(); 36 | } 37 | 38 | void MainTest::pointer() 39 | { 40 | QInjection::Pointer a; 41 | QCOMPARE(a->add(2, 3), 5); 42 | } 43 | 44 | int run_inject(int n1, int n2, Adder *a = QInjection::Inject) 45 | { 46 | return a->add(n1, n2); 47 | } 48 | 49 | void MainTest::inject() 50 | { 51 | QCOMPARE(run_inject(7, 3), 10); 52 | } 53 | 54 | void MainTest::get() 55 | { 56 | auto a = QInjection::create(); 57 | QCOMPARE(a->add(7, 3), 10); 58 | } 59 | 60 | void MainTest::scopped() 61 | { 62 | int v1{0}; 63 | int v2{0}; 64 | { 65 | QInjection::Pointer h1; 66 | v1 = h1->value(); 67 | } 68 | { 69 | QInjection::Pointer h2; 70 | v2 = h2->value(); 71 | } 72 | QCOMPARE(v1, 1); 73 | QCOMPARE(v2, 2); 74 | QTEST_ASSERT(v1 != v2); 75 | } 76 | 77 | void MainTest::scope_lifetime() 78 | { 79 | QInjection::addScopped(createLifeTimeReporter); 80 | 81 | QInjection::Pointer l; 82 | QCOMPARE(lifeTime, true); 83 | qApp->processEvents(); 84 | } 85 | 86 | void MainTest::check_scope_lifetime() 87 | { 88 | QCOMPARE(lifeTime, false); 89 | } 90 | 91 | bool run_lifetime_inject(LifeTimeReporter *l = QInjection::Inject) 92 | { 93 | Q_UNUSED(l); 94 | return lifeTime; 95 | } 96 | 97 | void MainTest::scope_lifetime2() 98 | { 99 | run_lifetime_inject(); 100 | QCOMPARE(lifeTime, true); 101 | qApp->processEvents(); 102 | } 103 | 104 | void MainTest::check_scope_lifetime2() 105 | { 106 | QCOMPARE(lifeTime, false); 107 | } 108 | 109 | QTEST_MAIN(MainTest) 110 | -------------------------------------------------------------------------------- /tests/main/tst_main.h: -------------------------------------------------------------------------------- 1 | #ifndef TST_MAIN_H 2 | #define TST_MAIN_H 3 | 4 | #include 5 | #include 6 | #include "dependencypointer.h" 7 | 8 | class Adder; 9 | class MainTest : public QObject 10 | { 11 | Q_OBJECT 12 | QInjection::Pointer tmp; 13 | 14 | public: 15 | MainTest(QObject *parent = nullptr); 16 | 17 | private slots: 18 | void initTestCase(); 19 | void pointer(); 20 | void inject(); 21 | void get(); 22 | void scopped(); 23 | void scope_lifetime(); 24 | void check_scope_lifetime(); 25 | void scope_lifetime2(); 26 | void check_scope_lifetime2(); 27 | }; 28 | 29 | #endif // TST_MAIN_H 30 | -------------------------------------------------------------------------------- /tests/tests.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = subdirs 2 | 3 | SUBDIRS += \ 4 | NewAPI \ 5 | auto_create \ 6 | main 7 | --------------------------------------------------------------------------------