/usr/include/injeqt/module.h is in libinjeqt-dev 1.0.1-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 | /*
* %injeqt copyright begin%
* Copyright 2014 RafaĆ Malinowski (rafal.przemyslaw.malinowski@gmail.com)
* %injeqt copyright end%
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#include <injeqt/injeqt.h>
#include <injeqt/type.h>
#include <memory>
/**
* @file
* @brief Contains classes and functions for creating modules.
*/
namespace injeqt { namespace internal {
class injector_impl;
class module_impl;
}}
namespace injeqt { namespace v1 {
/**
* @brief Module represents set of types and objects that can be injected and that can use injections.
*
* Injector is normally constructed from set of modules, each one contains
* group of related types.
*
* Modules are move-only types and cannot by copied.
*
* To add a module to system one must inherit from it and configure it in constructor and
* then pass instance of it to created injector class.
*
* Set of types in given module does not have to fully satify each one dependencies - it
* is only required for a group of modules passed into injector.
*
* Module configuration is done by calling any of add_* method. Currently implemnted are:
* add_ready_object, add_type, add_factory.
*/
class INJEQT_API module
{
public:
module();
virtual ~module();
protected:
/**
* @brief Add already constructed object to module.
* @tparam T type of added object (must be inherited from QObject).
* @param object added object
* @throw qobject_type when passed type @p T represents QObject
* @throw invalid_qobject when passed @p object is nullptr or does not have valid QMetaObject
* @throw interface_not_implemented when passed @p object does not implements type @p T
*
* It has to be fully constructed and must not expect any injection to take place on it
* (even if it has INJEQT_SETTER methods). However this object could be injected into other
* ones as it if is of type T.
*
* Real type of object must be same as T or descend from it. In other cases an exception
* will be thrown.
*
* Module class does not take ownership of this object. Either subclass of module must do
* it in any way or calee must ensure that object will be destroyed after module is destroyed.
*
* Example usage:
*
* class injectable : public QObject
* {
* Q_OBJECT
* };
*
* class ready_module : public module
* {
* ready_module()
* {
* _ready_object = std::make_unique<injectable>();
* add_ready_object<injectable>(_ready_object.get());
* }
* };
*
* class ready_module2 : public module
* {
* ready_module2(injectable *ready_object)
* {
* add_ready_object<injectable>(ready_object);
* }
* };
*
* In second example responsibility for ready_object's lifetime lies on ready_module2 object
* creator.
*
* When injector object is created with any of these modules this code will lead to return
* the same object thas was passed to add_ready_object method:
*
* auto o = injector.get<injectable>();
*/
template<typename T>
void add_ready_object(QObject *object)
{
add_ready_object(make_type<T>(), object);
}
/**
* @brief Add type that can be default-constructed to module.
* @tparam T type added to module (must be inherited from QObject).
* @throw qobject_type when passed type @p T represents QObject
* @throw default_constructor_not_found is @p T does not have default constructor tagged with Q_INVOKABLE
*
* When an object of that type (or one of inherited types) is requested from injector or
* as a dependency to other objects then default constructor of T is invoked to create it.
* This constructor must be marked with Q_INVOKABLE macro and must not have any parameters
* (even with default values). In other cases this method will throw an exception.
*
* After object of type T is created it will be injected will all required dependencies
* and it will remain in cache until owning injector object exists. Onle one instance of
* T will exist at one time inside injector (this may change when in future scope abstraction
* will be added to library, but it won't affect default behavior). Injector takes ownership
* of created T object.
*
* Example usage:
*
* class injectable : public QObject
* {
* Q_OBJECT
* public:
* Q_INVOKABLE injectable() {}
* };
*
* class type_module : public module
* {
* type_module()
* {
* add_type<injectable>();
* }
* };
*
* When injector object is created with that modules this code will lead to creation of new object
* of type injectable (for o1) and return it and (for o2) to return it again.
*
* auto o1 = injector.get<injectable>();
* auto o2 = injector.get<injectable>();
*/
template<typename T>
void add_type()
{
add_type(make_type<T>());
}
/**
* @brief Add type that can be created by factory to module.
* @tparam T type added to module (must be inherited from QObject).
* @tparam F factory type (must be inherited from QObject).
* @throw qobject_type when passed type @p T represents QObject
* @throw qobject_type when passed type @p F represents QObject
* @throw unique_factory_method_not_found when type F does not have unique factory method for T
*
* When an object of that type (or one of inherited types) is requested from injector or
* as a dependency to other objects then object of type F is requted first and its method
* returning pointer to T* and not accepting any arguments if called to create T object.
* Type F must be registered in any of injector modules.
*
* Type F must contain exactly one method marked with Q_INVOKABLE macro that returns object
* of type T* and does not have any arguments. In other case an exception will be thrown.
* Qt meta-object system unfortunately does not allow us to require returned type to be
* std::unique_ptr<T> which would make object ownership clear in code.
*
* After object of type T is created it will be injected will all required dependencies
* and it will remain in cache until owning injector object exists. Onle one instance of
* T will exist at one time inside injector (this may change when in future scope abstraction
* will be added to library, but it won't affect default behavior). Injector takes ownership
* of created T object.
*
* Example usage:
*
* class injectable : public QObject
* {
* Q_OBJECT
* public:
* injectable(int arg) { (void)arg; }
* };
*
* class injectable_factory : public QObject
* {
* Q_OBJECT
* public:
* Q_INVOKABLE injectable_factory() {}
* Q_INVOKABLE injectable * create()
* { return new injectable{2}; }
* };
*
* class type_module : public module
* {
* type_module()
* {
* add_type<injectable_factory>();
* add_factory<injectable, injectable_factory>();
* }
* };
*
* Note that injectable constructor does not have to be maked with Q_INVOKABLE. Also note that
* injectable_factory had to be added itself to module (it could be added in another module
* that would have to be included into final injector).
*
* When injector object is created with that modules this code will lead to creation of new object
* of type injectable_factory (for o1) and then in call of injectable_factory::create(). Second line
* will lead to return of cached object (the same as o1) without any additional calls.
*
* auto o1 = injector.get<injectable>();
* auto o2 = injector.get<injectable>();
*/
template<typename T, typename F>
void add_factory()
{
add_factory(make_type<T>(), make_type<F>());
}
private:
friend class ::injeqt::internal::injector_impl;
std::unique_ptr<injeqt::internal::module_impl> _pimpl;
/**
* @see add_ready_object<T>(QObject *);
* @pre !t.is_empty()
*/
void add_ready_object(type t, QObject *object);
/**
* @see add_type<T>();
* @pre !t.is_empty()
*/
void add_type(type t);
/**
* @see add_factory<T, F>();
* @pre !t.is_empty()
* @pre !f.is_empty()
*/
void add_factory(type t, type f);
};
}}
|