diff --git a/.github/workflows/CodeCoverage.yml b/.github/workflows/CodeCoverage.yml new file mode 100644 index 0000000..0f0248f --- /dev/null +++ b/.github/workflows/CodeCoverage.yml @@ -0,0 +1,33 @@ +name: Code Coverage + +on: + push: + branches: [ "dev", "main" ] + paths-ignore: + - "Docs/**" + - ".readthedocs.yaml" + - "README.md" + +jobs: + code-coverage: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: Create Build Environment + run: cmake -E make_directory ${{runner.workspace}}/build + + - name: Configure + run: cmake -B ${{runner.workspace}}/build -D_7BIT_DI_LIBRARY_TYPE=Static -D_7BIT_DI_BUILD_ALL_TESTS=ON -DCMAKE_CXX_FLAGS="-coverage" + + - name: Build + run: cmake --build ${{runner.workspace}}/build -j + + - name: Test + working-directory: ${{runner.workspace}}/build + run: ctest --output-on-failure + + - name: Upload Code Coverage + working-directory: ${{runner.workspace}}/build + run: bash <(curl -s https://codecov.io/bash) -t ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/DevCI.yml b/.github/workflows/DevCI.yml index 4bcd698..378cf39 100644 --- a/.github/workflows/DevCI.yml +++ b/.github/workflows/DevCI.yml @@ -36,6 +36,4 @@ jobs: - name: Test working-directory: ${{runner.workspace}}/build - run: ctest -C ${{matrix.build_type}} - env: - CTEST_OUTPUT_ON_FAILURE: True + run: ctest -C ${{matrix.build_type}} --output-on-failure diff --git a/.github/workflows/Linux.yml b/.github/workflows/Linux.yml index 30598f2..82f8a63 100644 --- a/.github/workflows/Linux.yml +++ b/.github/workflows/Linux.yml @@ -82,6 +82,4 @@ jobs: - name: Test working-directory: ${{runner.workspace}}/build - run: ctest -C ${{matrix.build_type}} - env: - CTEST_OUTPUT_ON_FAILURE: True + run: ctest -C ${{matrix.build_type}} --output-on-failure diff --git a/.github/workflows/MacOs.yml b/.github/workflows/MacOs.yml index 8c2da18..1091706 100644 --- a/.github/workflows/MacOs.yml +++ b/.github/workflows/MacOs.yml @@ -54,6 +54,4 @@ jobs: - name: Test working-directory: ${{runner.workspace}}/build - run: ctest -C ${{matrix.build_type}} - env: - CTEST_OUTPUT_ON_FAILURE: True + run: ctest -C ${{matrix.build_type}} --output-on-failure diff --git a/.github/workflows/Windows.yml b/.github/workflows/Windows.yml index f2c578f..1aff30c 100644 --- a/.github/workflows/Windows.yml +++ b/.github/workflows/Windows.yml @@ -80,6 +80,4 @@ jobs: - name: Test working-directory: ${{runner.workspace}}/build - run: ctest -C ${{matrix.build_type}} - env: - CTEST_OUTPUT_ON_FAILURE: True + run: ctest -C ${{matrix.build_type}} --output-on-failure diff --git a/CMakeLists.txt b/CMakeLists.txt index 4b950b3..9e5854f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.15.0) set(_7BIT_DI_LIBRARY 7bitDI) set(_7BIT_DI_VERSION_MAJOR 3) -set(_7BIT_DI_VERSION_MINOR 1) +set(_7BIT_DI_VERSION_MINOR 2) set(_7BIT_DI_VERSION_PATCH 0) set(_7BIT_DI_VERSION ${_7BIT_DI_VERSION_MAJOR}.${_7BIT_DI_VERSION_MINOR}.${_7BIT_DI_VERSION_PATCH}) diff --git a/Cmake/Setup.cmake b/Cmake/Setup.cmake index c0ff726..129a186 100644 --- a/Cmake/Setup.cmake +++ b/Cmake/Setup.cmake @@ -31,24 +31,6 @@ set(_7BIT_DI_DI_DIR "${_7BIT_DI_INCLUDE_DIR}/SevenBit/DI") set(_7BIT_DI_DETAILS_DIR "${_7BIT_DI_DI_DIR}/Details") set(_7BIT_DI_MAIN_HEADER "${_7BIT_DI_INCLUDE_DIR}/SevenBit/DI.hpp") -file(GLOB _7BIT_DI_TOP_HEADERS "${_7BIT_DI_DI_DIR}/*.hpp") -file(GLOB _7BIT_DI_DETAILS_HEADERS - "${_7BIT_DI_DETAILS_DIR}/Containers/*.hpp" - "${_7BIT_DI_DETAILS_DIR}/Core/*.hpp" - "${_7BIT_DI_DETAILS_DIR}/Factories/*.hpp" - "${_7BIT_DI_DETAILS_DIR}/Helpers/*.hpp" - "${_7BIT_DI_DETAILS_DIR}/Services/*.hpp" - "${_7BIT_DI_DETAILS_DIR}/Utils/*.hpp" -) -file(GLOB _7BIT_DI_IMPL_HEADERS - "${_7BIT_DI_DI_DIR}/Impl/*.hpp" - "${_7BIT_DI_DETAILS_DIR}/Containers/Impl/*.hpp" - "${_7BIT_DI_DETAILS_DIR}/Core/Impl/*.hpp" - "${_7BIT_DI_DETAILS_DIR}/Factories/Impl/*.hpp" - "${_7BIT_DI_DETAILS_DIR}/Helpers/Impl/*.hpp" - "${_7BIT_DI_DETAILS_DIR}/Utils/Impl/*.hpp" -) -set(_7BIT_DI_ALL_HEADERS ${_7BIT_DI_MAIN_HEADER} ${_7BIT_DI_TOP_HEADERS} ${_7BIT_DI_DETAILS_HEADERS} ${_7BIT_DI_IMPL_HEADERS}) set(_7BIT_DI_LIBRARY_TYPE "Static" CACHE STRING "Library build type: Shared;Static;HeaderOnly") set(_7BIT_DI_LIBRARY_TYPE_VALUES "Shared;Static;HeaderOnly" CACHE STRING "List of possible _7BIT_DI_LIBRARY_TYPE values") diff --git a/Docs/advanced-guides/using-aliases.rst b/Docs/advanced-guides/using-aliases.rst index fe2f284..5d82c33 100644 --- a/Docs/advanced-guides/using-aliases.rst +++ b/Docs/advanced-guides/using-aliases.rst @@ -2,8 +2,12 @@ Using Aliases ======================================== With the use of aliases, one service can be injected through its multiple base classes, also aliases can be chained. -If multiple aliases are registered with the same base class only last will be used. +In case of injecting multiple aliases all real services will be fetched. +.. warning:: + Using aliases is resource intensive, especially for injecting transient and multiple services, provider recursively + traverses through aliases chain to find proper service. Mixing scoped and singleton aliases for same base type will + lead to undefined behavior .. literalinclude:: ../../Examples/Guides/ServiceAliases.cpp :caption: Examples/Guides/ServiceAliases diff --git a/Docs/conf.py b/Docs/conf.py index ee0c007..5ec2320 100644 --- a/Docs/conf.py +++ b/Docs/conf.py @@ -12,7 +12,7 @@ def createIfNotExists(path): project = "7bitDI" copyright = "2023, 7BitCoder Sylwester Dawida" author = "Sylwester Dawida" -version = "3.1.0" +version = "3.2.0" extensions = [ "sphinx.ext.autodoc", diff --git a/Docs/getting-started.rst b/Docs/getting-started.rst index b2e497e..79fb6e7 100644 --- a/Docs/getting-started.rst +++ b/Docs/getting-started.rst @@ -36,7 +36,7 @@ Installation FetchContent_Declare( 7bitDI GIT_REPOSITORY https://github.com/7bitcoder/7bitDI.git - GIT_TAG v3.1.0 + GIT_TAG v3.2.0 ) FetchContent_MakeAvailable(7bitDI) @@ -48,7 +48,7 @@ Installation .. code-block:: Txt [requires] - 7bitdi/3.1.0 + 7bitdi/3.2.0 change the version to newer if available, then run the command: diff --git a/Docs/reference/di/details/core.rst b/Docs/reference/di/details/core.rst index d779969..04b3d47 100644 --- a/Docs/reference/di/details/core.rst +++ b/Docs/reference/di/details/core.rst @@ -6,7 +6,7 @@ sb::di::details - Core :titlesonly: core/iserviceinstanceproviderroot.rst - core/serviceinstancecreator.rst + core/servicealiasescreator.rst core/serviceinstanceprovider.rst core/serviceinstanceproviderroot.rst - core/serviceinstancesresolver.rst + core/serviceinstancescreator.rst diff --git a/Docs/reference/di/details/core/servicealiasescreator.rst b/Docs/reference/di/details/core/servicealiasescreator.rst new file mode 100644 index 0000000..cca4437 --- /dev/null +++ b/Docs/reference/di/details/core/servicealiasescreator.rst @@ -0,0 +1,6 @@ +ServiceAliasesCreator +======================================== + +.. doxygenclass:: sb::di::details::ServiceAliasesCreator + :members: + :undoc-members: diff --git a/Docs/reference/di/details/core/serviceinstancecreator.rst b/Docs/reference/di/details/core/serviceinstancecreator.rst deleted file mode 100644 index cac9a41..0000000 --- a/Docs/reference/di/details/core/serviceinstancecreator.rst +++ /dev/null @@ -1,6 +0,0 @@ -ServiceInstanceCreator -======================================== - -.. doxygenclass:: sb::di::details::ServiceInstanceCreator - :members: - :undoc-members: diff --git a/Docs/reference/di/details/core/serviceinstancescreator.rst b/Docs/reference/di/details/core/serviceinstancescreator.rst new file mode 100644 index 0000000..07d6756 --- /dev/null +++ b/Docs/reference/di/details/core/serviceinstancescreator.rst @@ -0,0 +1,6 @@ +ServiceInstancesCreator +======================================== + +.. doxygenclass:: sb::di::details::ServiceInstancesCreator + :members: + :undoc-members: diff --git a/Docs/reference/di/details/core/serviceinstancesresolver.rst b/Docs/reference/di/details/core/serviceinstancesresolver.rst deleted file mode 100644 index 24225f7..0000000 --- a/Docs/reference/di/details/core/serviceinstancesresolver.rst +++ /dev/null @@ -1,6 +0,0 @@ -ServiceInstancesResolver -======================================== - -.. doxygenclass:: sb::di::details::ServiceInstancesResolver - :members: - :undoc-members: diff --git a/Include/SevenBit/DI/CmakeDef.hpp b/Include/SevenBit/DI/CmakeDef.hpp index 1f3aa90..9dcd81a 100644 --- a/Include/SevenBit/DI/CmakeDef.hpp +++ b/Include/SevenBit/DI/CmakeDef.hpp @@ -13,5 +13,5 @@ #endif #define _7BIT_DI_VERSION_MAJOR 3 -#define _7BIT_DI_VERSION_MINOR 1 +#define _7BIT_DI_VERSION_MINOR 2 /* #undef _7BIT_DI_VERSION_PATCH */ diff --git a/Include/SevenBit/DI/Details/Containers/Impl/ServiceDescriptorList.hpp b/Include/SevenBit/DI/Details/Containers/Impl/ServiceDescriptorList.hpp index 92a4f84..5788567 100644 --- a/Include/SevenBit/DI/Details/Containers/Impl/ServiceDescriptorList.hpp +++ b/Include/SevenBit/DI/Details/Containers/Impl/ServiceDescriptorList.hpp @@ -7,12 +7,6 @@ namespace sb::di::details { - - INLINE ServiceDescriptorList::ServiceDescriptorList(ServiceDescriptor &&descriptor) - : _oneOrList(std::move(descriptor)) - { - } - INLINE void ServiceDescriptorList::add(ServiceDescriptor &&descriptor) { if (!empty()) @@ -22,20 +16,9 @@ namespace sb::di::details checkAlias(descriptor); checkLifeTime(descriptor); } - _oneOrList.add(std::move(descriptor)); + OneOrList::add(std::move(descriptor)); } - INLINE OneOrList &ServiceDescriptorList::getInnerList() { return _oneOrList; } - INLINE const OneOrList &ServiceDescriptorList::getInnerList() const { return _oneOrList; } - - INLINE const ServiceDescriptor &ServiceDescriptorList::first() const { return _oneOrList.first(); } - - INLINE const ServiceDescriptor &ServiceDescriptorList::last() const { return _oneOrList.last(); } - - INLINE bool ServiceDescriptorList::empty() const { return _oneOrList.empty(); } - - INLINE std::size_t ServiceDescriptorList::size() const { return _oneOrList.size(); } - INLINE ServiceLifeTime ServiceDescriptorList::getLifeTime() const { return first().getLifeTime(); } INLINE TypeId ServiceDescriptorList::getServiceTypeId() const { return first().getServiceTypeId(); } @@ -76,7 +59,4 @@ namespace sb::di::details throw ServiceLifeTimeMismatchException{descriptor.getImplementationTypeId(), getServiceTypeId()}; } } - - INLINE void ServiceDescriptorList::seal() { _oneOrList.shrink(); } - } // namespace sb::di::details diff --git a/Include/SevenBit/DI/Details/Containers/Impl/ServiceInstanceList.hpp b/Include/SevenBit/DI/Details/Containers/Impl/ServiceInstanceList.hpp deleted file mode 100644 index 8dd6d46..0000000 --- a/Include/SevenBit/DI/Details/Containers/Impl/ServiceInstanceList.hpp +++ /dev/null @@ -1,59 +0,0 @@ -#pragma once - -#include "SevenBit/DI/LibraryConfig.hpp" - -#include "SevenBit/DI/Details/Containers/ServiceInstanceList.hpp" -#include "SevenBit/DI/Details/Utils/RequireInstance.hpp" - -namespace sb::di::details -{ - INLINE ServiceInstanceList::ServiceInstanceList(const std::size_t size) : _oneOrList(size) {} - - INLINE ServiceInstanceList::ServiceInstanceList(ServiceInstance instance) - : _oneOrList(RequireInstance::validAndGet(std::move(instance))) - { - } - - INLINE void ServiceInstanceList::add(ServiceInstance &&instance) - { - _oneOrList.add(RequireInstance::validAndGet(std::move(instance))); - } - - INLINE OneOrList &ServiceInstanceList::getInnerList() { return _oneOrList; } - INLINE const OneOrList &ServiceInstanceList::getInnerList() const { return _oneOrList; } - - INLINE ServiceInstance &ServiceInstanceList::first() { return _oneOrList.first(); } - INLINE const ServiceInstance &ServiceInstanceList::first() const { return _oneOrList.first(); } - - INLINE ServiceInstance &ServiceInstanceList::last() { return _oneOrList.last(); } - INLINE const ServiceInstance &ServiceInstanceList::last() const { return _oneOrList.last(); } - - INLINE std::size_t ServiceInstanceList::size() const { return _oneOrList.size(); } - - INLINE bool ServiceInstanceList::empty() const { return _oneOrList.empty(); } - - INLINE void ServiceInstanceList::reserve(const std::size_t newCapacity) { return _oneOrList.reserve(newCapacity); } - - INLINE void ServiceInstanceList::shrink() { return _oneOrList.shrink(); } - - INLINE void ServiceInstanceList::seal() - { - _oneOrList.shrink(); - _sealed = true; - } - - INLINE bool ServiceInstanceList::isSealed() const { return _sealed; } - - INLINE void ServiceInstanceList::clear() - { - if (const auto single = _oneOrList.tryGetAsSingle()) - { - single->clear(); - } - else - { - _oneOrList.getAsList().clear(); - } - } - -} // namespace sb::di::details diff --git a/Include/SevenBit/DI/Details/Containers/ServiceDescriptorList.hpp b/Include/SevenBit/DI/Details/Containers/ServiceDescriptorList.hpp index 0d86029..c9235b8 100644 --- a/Include/SevenBit/DI/Details/Containers/ServiceDescriptorList.hpp +++ b/Include/SevenBit/DI/Details/Containers/ServiceDescriptorList.hpp @@ -9,12 +9,10 @@ namespace sb::di::details { - class EXPORT ServiceDescriptorList + class EXPORT ServiceDescriptorList : public OneOrList { - OneOrList _oneOrList; - public: - explicit ServiceDescriptorList(ServiceDescriptor &&descriptor); + using OneOrList::OneOrList; ServiceDescriptorList(const ServiceDescriptorList &) = delete; ServiceDescriptorList(ServiceDescriptorList &&) = default; @@ -22,22 +20,8 @@ namespace sb::di::details ServiceDescriptorList &operator=(const ServiceDescriptorList &) = delete; ServiceDescriptorList &operator=(ServiceDescriptorList &&) = default; - OneOrList &getInnerList(); - [[nodiscard]] const OneOrList &getInnerList() const; - void add(ServiceDescriptor &&descriptor); - [[nodiscard]] auto begin() const { return _oneOrList.getAsList().begin(); } - [[nodiscard]] auto end() const { return _oneOrList.getAsList().end(); } - - [[nodiscard]] const ServiceDescriptor &first() const; - - [[nodiscard]] const ServiceDescriptor &last() const; - - [[nodiscard]] bool empty() const; - - [[nodiscard]] std::size_t size() const; - [[nodiscard]] ServiceLifeTime getLifeTime() const; [[nodiscard]] TypeId getServiceTypeId() const; @@ -46,8 +30,6 @@ namespace sb::di::details [[nodiscard]] bool isAlias() const; - void seal(); - private: void checkBaseType(const ServiceDescriptor &descriptor) const; void checkKey(const ServiceDescriptor &descriptor) const; diff --git a/Include/SevenBit/DI/Details/Containers/ServiceDescriptorsMap.hpp b/Include/SevenBit/DI/Details/Containers/ServiceDescriptorsMap.hpp index 23711fa..74c5eba 100644 --- a/Include/SevenBit/DI/Details/Containers/ServiceDescriptorsMap.hpp +++ b/Include/SevenBit/DI/Details/Containers/ServiceDescriptorsMap.hpp @@ -36,9 +36,10 @@ namespace sb::di::details } ServiceDescriptorsMap(const ServiceDescriptorsMap &) = delete; - ServiceDescriptorsMap(ServiceDescriptorsMap &&) noexcept = default; + ServiceDescriptorsMap(ServiceDescriptorsMap &&) = default; ServiceDescriptorsMap &operator=(const ServiceDescriptorsMap &) = delete; + ServiceDescriptorsMap &operator=(ServiceDescriptorsMap &&) = delete; void add(ServiceDescriptor descriptor); diff --git a/Include/SevenBit/DI/Details/Containers/ServiceInstanceList.hpp b/Include/SevenBit/DI/Details/Containers/ServiceInstanceList.hpp index 4044004..61a48e6 100644 --- a/Include/SevenBit/DI/Details/Containers/ServiceInstanceList.hpp +++ b/Include/SevenBit/DI/Details/Containers/ServiceInstanceList.hpp @@ -7,14 +7,12 @@ namespace sb::di::details { - class EXPORT ServiceInstanceList + class ServiceInstanceList : public OneOrList { - OneOrList _oneOrList; bool _sealed = false; public: - explicit ServiceInstanceList(ServiceInstance instance); - explicit ServiceInstanceList(std::size_t size); + using OneOrList::OneOrList; ServiceInstanceList(const ServiceInstanceList &) = delete; ServiceInstanceList(ServiceInstanceList &&) = default; @@ -22,38 +20,7 @@ namespace sb::di::details ServiceInstanceList &operator=(const ServiceInstanceList &) = delete; ServiceInstanceList &operator=(ServiceInstanceList &&) = default; - void add(ServiceInstance &&instance); - - [[nodiscard]] auto begin() const { return _oneOrList.getAsList().begin(); } - [[nodiscard]] auto end() const { return _oneOrList.getAsList().end(); } - - OneOrList &getInnerList(); - [[nodiscard]] const OneOrList &getInnerList() const; - - ServiceInstance &first(); - [[nodiscard]] const ServiceInstance &first() const; - - ServiceInstance &last(); - [[nodiscard]] const ServiceInstance &last() const; - - [[nodiscard]] std::size_t size() const; - - [[nodiscard]] bool empty() const; - - void reserve(std::size_t newCapacity); - - void shrink(); - - void seal(); - - [[nodiscard]] bool isSealed() const; - - void clear(); - - ~ServiceInstanceList() = default; + void seal() { _sealed = true; } + [[nodiscard]] bool isSealed() const { return _sealed; } }; } // namespace sb::di::details - -#ifdef _7BIT_DI_ADD_IMPL -#include "SevenBit/DI/Details/Containers/Impl/ServiceInstanceList.hpp" -#endif diff --git a/Include/SevenBit/DI/Details/Containers/ServiceInstancesMap.hpp b/Include/SevenBit/DI/Details/Containers/ServiceInstancesMap.hpp index 1a34ea1..c764f2b 100644 --- a/Include/SevenBit/DI/Details/Containers/ServiceInstancesMap.hpp +++ b/Include/SevenBit/DI/Details/Containers/ServiceInstancesMap.hpp @@ -23,9 +23,10 @@ namespace sb::di::details explicit ServiceInstancesMap(bool strongDestructionOrder = false); ServiceInstancesMap(const ServiceInstancesMap &) = delete; - ServiceInstancesMap(ServiceInstancesMap &&) noexcept = default; + ServiceInstancesMap(ServiceInstancesMap &&) = default; ServiceInstancesMap &operator=(const ServiceInstancesMap &) = delete; + ServiceInstancesMap &operator=(ServiceInstancesMap &&) = delete; ServiceInstanceList &insert(const ServiceId &id, ServiceInstance &&instance); diff --git a/Include/SevenBit/DI/Details/Core/IServiceInstanceProviderRoot.hpp b/Include/SevenBit/DI/Details/Core/IServiceInstanceProviderRoot.hpp index 15e9014..2005116 100644 --- a/Include/SevenBit/DI/Details/Core/IServiceInstanceProviderRoot.hpp +++ b/Include/SevenBit/DI/Details/Core/IServiceInstanceProviderRoot.hpp @@ -4,7 +4,7 @@ #include "SevenBit/DI/Details/Containers/ServiceDescriptorsMap.hpp" #include "SevenBit/DI/Details/Containers/ServiceInstancesMap.hpp" -#include "SevenBit/DI/Details/Core/ServiceInstanceCreator.hpp" +#include "SevenBit/DI/Details/Core/ServiceInstancesCreator.hpp" namespace sb::di::details { @@ -14,7 +14,7 @@ namespace sb::di::details virtual ServiceInstancesMap &getSingletons() = 0; - virtual ServiceInstanceCreator &getRootInstanceCreator() = 0; + virtual ServiceInstancesCreator &getRootCreator() = 0; virtual ~IServiceInstanceProviderRoot() = default; }; diff --git a/Include/SevenBit/DI/Details/Core/Impl/ServiceAliasesCreator.hpp b/Include/SevenBit/DI/Details/Core/Impl/ServiceAliasesCreator.hpp new file mode 100644 index 0000000..53c6287 --- /dev/null +++ b/Include/SevenBit/DI/Details/Core/Impl/ServiceAliasesCreator.hpp @@ -0,0 +1,70 @@ +#pragma once + +#include +#include + +#include "SevenBit/DI/LibraryConfig.hpp" + +#include "SevenBit/DI/Details/Core/ServiceAliasesCreator.hpp" +#include "SevenBit/DI/Details/Services/AliasService.hpp" +#include "SevenBit/DI/Details/Utils/RequireDescriptor.hpp" +#include "SevenBit/DI/Details/Utils/RequireInstance.hpp" + +namespace sb::di::details +{ + INLINE ServiceInstance ServiceAliasesCreator::tryCreate(const ServiceDescriptor &descriptor, + const ServiceInstance *original) const + { + return original ? create(descriptor, *original) : ServiceInstance{}; + } + + INLINE ServiceInstance ServiceAliasesCreator::tryMap(const ServiceDescriptor &descriptor, + ServiceInstance &&original) const + { + original.addCastOffset(descriptor.getCastOffset()); + return std::move(original); + } + + INLINE void ServiceAliasesCreator::tryCreateAll(ServiceInstanceList &instances, const ServiceDescriptor &descriptor, + const OneOrList *originals, + const std::size_t skipLast) const + { + if (originals) + { + const auto size = originals->size(); + const auto take = skipLast <= size ? size - skipLast : 0; + instances.reserve(size); + originals->forEach([&](const ServiceInstance &instance, const std::size_t index) { + if (index < take) + { + instances.add(create(descriptor, instance)); + } + }); + } + } + + INLINE void ServiceAliasesCreator::tryMapAll(ServiceInstanceList &instances, const ServiceDescriptor &descriptor, + OneOrList &&originals) const + { + if (originals) + { + if (descriptor.getCastOffset()) + { + originals.forEach( + [&](ServiceInstance &instance) { instance.addCastOffset(descriptor.getCastOffset()); }); + } + instances.addList(std::move(originals)); + } + } + + INLINE ServiceInstance ServiceAliasesCreator::create(const ServiceDescriptor &descriptor, + const ServiceInstance &original) const + { + RequireDescriptor::alias(descriptor); + RequireInstance::valid(original); + + auto implementation = + std::make_unique(original.getAs(), descriptor.getImplementationTypeId()); + return ServiceInstance{std::move(implementation), descriptor.getCastOffset()}; + } +} // namespace sb::di::details diff --git a/Include/SevenBit/DI/Details/Core/Impl/ServiceInstanceCreator.hpp b/Include/SevenBit/DI/Details/Core/Impl/ServiceInstanceCreator.hpp deleted file mode 100644 index 0ea3548..0000000 --- a/Include/SevenBit/DI/Details/Core/Impl/ServiceInstanceCreator.hpp +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once - -#include - -#include "SevenBit/DI/LibraryConfig.hpp" - -#include "SevenBit/DI/Details/Core/ServiceInstanceCreator.hpp" -#include "SevenBit/DI/Details/Services/AliasService.hpp" -#include "SevenBit/DI/Details/Utils/Require.hpp" -#include "SevenBit/DI/Details/Utils/RequireDescriptor.hpp" -#include "SevenBit/DI/Details/Utils/RequireInstance.hpp" - -namespace sb::di::details -{ - INLINE void ServiceInstanceCreator::setServiceProvider(ServiceProvider &serviceProvider) - { - _serviceProvider = &serviceProvider; - } - - INLINE ServiceInstance ServiceInstanceCreator::createInstance(const ServiceDescriptor &descriptor, - const bool inPlaceRequest) - { - RequireDescriptor::nonAlias(descriptor); - auto &provider = *Require::notNullAndGet(_serviceProvider); - const auto &factory = *Require::notNullAndGet(descriptor.getImplementationFactory()); - auto _ = _circularDependencyGuard(descriptor.getImplementationTypeId()); - - auto implementation = factory.createInstance(provider, inPlaceRequest); - return createInstance(std::move(implementation), descriptor.getCastOffset()); - } - - INLINE ServiceInstance ServiceInstanceCreator::createInstanceAlias(const ServiceDescriptor &descriptor, - const ServiceInstance &instance) - { - RequireDescriptor::alias(descriptor); - RequireInstance::valid(instance); - auto implementationType = descriptor.getImplementationTypeId(); - - auto implementation = std::make_unique(instance.getAs(), implementationType); - return createInstance(std::move(implementation), descriptor.getCastOffset()); - } - - INLINE ServiceInstance ServiceInstanceCreator::createInstance(IServiceInstance::Ptr &&implementation, - const ptrdiff_t castOffset) - { - return RequireInstance::validAndGet(ServiceInstance{std::move(implementation), castOffset}); - } -} // namespace sb::di::details diff --git a/Include/SevenBit/DI/Details/Core/Impl/ServiceInstanceProvider.hpp b/Include/SevenBit/DI/Details/Core/Impl/ServiceInstanceProvider.hpp index d4b06af..9d39b3c 100644 --- a/Include/SevenBit/DI/Details/Core/Impl/ServiceInstanceProvider.hpp +++ b/Include/SevenBit/DI/Details/Core/Impl/ServiceInstanceProvider.hpp @@ -20,7 +20,7 @@ namespace sb::di::details INLINE void ServiceInstanceProvider::init(ServiceProvider &serviceProvider) { - _instanceCreator.setServiceProvider(serviceProvider); + _instancesCreator.setServiceProvider(serviceProvider); auto external = std::make_unique>(&serviceProvider); _scoped.insert(ServiceId{external->getTypeId()}, ServiceInstance{std::move(external)}).seal(); } @@ -42,35 +42,52 @@ namespace sb::di::details INLINE const ServiceInstance *ServiceInstanceProvider::tryGetInstance(const ServiceId &id) { - auto instances = findRegisteredInstances(id); - if (!instances) + if (const auto instances = findInstances(id)) { - if (const auto descriptors = findDescriptors(id, false)) + return &instances->last(); + } + if (const auto descriptors = findDescriptors(id)) + { + const auto &descriptor = descriptors->last(); + if (auto created = tryCreateInstance(descriptor)) { - instances = tryRegisterAndGet(id, *descriptors, tryCreateNonTransient(*descriptors)); + auto &inserted = getInstancesMap(getLifeTime(descriptor)).insert(id, std::move(created)); + if (!descriptor.isAlias() && descriptors->size() == 1) + { + inserted.seal(); + } + return &inserted.last(); } } - return instances ? &instances->last() : nullptr; + return nullptr; } INLINE const OneOrList *ServiceInstanceProvider::tryGetInstances(const ServiceId &id) { - auto instances = findRegisteredInstances(id); - if (!instances) + if (const auto instances = findInstances(id)) { - if (const auto descriptors = findDescriptors(id, false)) + if (!instances->isSealed()) { - instances = tryRegisterAndGet(id, *descriptors, tryCreateAllNonTransient(*descriptors)); + if (const auto descriptors = findDescriptors(id)) + { + auto newInstances = tryCreateInstances(*descriptors, instances->size()); + newInstances.addList(std::move(*instances)); + *instances = std::move(newInstances); + instances->seal(); + } } + return instances; } - else if (!instances->isSealed()) + if (const auto descriptors = findDescriptors(id)) { - if (const auto descriptors = findDescriptors(id, false)) + if (auto created = tryCreateInstances(*descriptors)) { - instances = createRestNonTransientAndGet(*descriptors, *instances); + auto &inserted = getInstancesMap(getLifeTime(descriptors->last())).insert(id, std::move(created)); + inserted.seal(); + return &inserted; } } - return instances ? &instances->getInnerList() : nullptr; + return nullptr; } INLINE ServiceInstance ServiceInstanceProvider::createInstance(const ServiceId &id) @@ -85,14 +102,14 @@ namespace sb::di::details INLINE ServiceInstance ServiceInstanceProvider::tryCreateInstance(const ServiceId &id) { - const auto descriptors = findDescriptors(id, true); - return descriptors ? tryCreateTransient(*descriptors) : ServiceInstance{}; + const auto descriptors = findTransientDescriptors(id); + return descriptors ? tryCreateTransientInstance(descriptors->last()) : ServiceInstance{}; } - INLINE std::optional> ServiceInstanceProvider::tryCreateInstances(const ServiceId &id) + INLINE OneOrList ServiceInstanceProvider::tryCreateInstances(const ServiceId &id) { - const auto descriptors = findDescriptors(id, true); - return descriptors ? tryCreateAllTransient(*descriptors) : std::nullopt; + const auto descriptors = findTransientDescriptors(id); + return descriptors ? tryCreateTransientInstances(*descriptors) : OneOrList{}; } INLINE ServiceInstance ServiceInstanceProvider::createInstanceInPlace(const ServiceId &id) @@ -108,15 +125,18 @@ namespace sb::di::details INLINE ServiceInstance ServiceInstanceProvider::tryCreateInstanceInPlace(const ServiceId &id) { - if (const auto descriptors = findDescriptors(id, true); - descriptors && !descriptors->isAlias() && descriptors->last().getImplementationTypeId() == id.getTypeId()) + if (const auto descriptors = findTransientDescriptors(id)) { - return makeResolver(*descriptors).createInstanceInPlace(); + if (const auto &descriptor = descriptors->last(); + !descriptor.isAlias() && descriptor.getImplementationTypeId() == id.getTypeId()) + { + return selectCreator(descriptor).createInPlace(descriptor); + } } return ServiceInstance{}; } - INLINE ServiceInstanceList *ServiceInstanceProvider::findRegisteredInstances(const ServiceId &id) + INLINE ServiceInstanceList *ServiceInstanceProvider::findInstances(const ServiceId &id) { const auto singletonsFirst = getOptions().searchInSigletonsFirst; auto &first = singletonsFirst ? _root.getSingletons() : _scoped; @@ -125,110 +145,90 @@ namespace sb::di::details return instances ? instances : second.findInstances(id); } - INLINE const ServiceDescriptorList *ServiceInstanceProvider::findDescriptors(const ServiceId &id, - const bool transient) const + INLINE const ServiceDescriptorList *ServiceInstanceProvider::findDescriptors(const ServiceId &id) const { - if (const auto descriptors = _root.getDescriptorsMap().findDescriptors(id)) - { - if (const auto isTransient = descriptors->getLifeTime().isTransient(); - descriptors->isAlias() || (transient ? isTransient : !isTransient)) - { - return descriptors; - } - } - return nullptr; + const auto descriptors = _root.getDescriptorsMap().findDescriptors(id); + const auto isCorrect = descriptors && (!descriptors->getLifeTime().isTransient() || descriptors->isAlias()); + return isCorrect ? descriptors : nullptr; } - INLINE ServiceInstanceList *ServiceInstanceProvider::tryRegisterAndGet( - const ServiceId &id, const ServiceDescriptorList &descriptors, std::optional &&instances) + INLINE const ServiceDescriptorList *ServiceInstanceProvider::findTransientDescriptors(const ServiceId &id) const { - if (instances) - { - auto &descriptor = descriptors.last(); - auto lifeTime = descriptor.getLifeTime(); - if (descriptor.isAlias()) - { - const ServiceId originalId{descriptor.getImplementationTypeId(), descriptor.getImplementationKey()}; - lifeTime = _scoped.contains(originalId) ? ServiceLifeTimes::Scoped : ServiceLifeTimes::Singleton; - } - auto &instancesMap = lifeTime.isSingleton() ? _root.getSingletons() : _scoped; - return &instancesMap.insert(id, std::move(*instances)); - } - return nullptr; + const auto descriptors = _root.getDescriptorsMap().findDescriptors(id); + const auto isCorrect = descriptors && (descriptors->getLifeTime().isTransient() || descriptors->isAlias()); + return isCorrect ? descriptors : nullptr; } - INLINE std::optional ServiceInstanceProvider::tryCreateNonTransient( - const ServiceDescriptorList &descriptors) + INLINE ServiceLifeTime ServiceInstanceProvider::getLifeTime(const ServiceDescriptor &descriptor) const { - if (!descriptors.isAlias()) + if (descriptor.isAlias()) { - RequireDescriptor::nonTransient(descriptors.first()); - return makeResolver(descriptors).createOneInstanceInPlace(); + const ServiceId originalId{descriptor.getImplementationTypeId(), descriptor.getImplementationKey()}; + return _scoped.contains(originalId) ? ServiceLifeTimes::Scoped : ServiceLifeTimes::Singleton; } - auto &last = descriptors.last(); - const auto original = tryGetInstance(ServiceId{last.getImplementationTypeId(), last.getImplementationKey()}); - return original ? std::make_optional(makeResolver(descriptors).createOneAlias(*original)) : std::nullopt; + return descriptor.getLifeTime(); } - INLINE std::optional ServiceInstanceProvider::tryCreateAllNonTransient( - const ServiceDescriptorList &descriptors) + INLINE ServiceInstancesMap &ServiceInstanceProvider::getInstancesMap(const ServiceLifeTime lifetime) { - if (!descriptors.isAlias()) - { - RequireDescriptor::nonTransient(descriptors.first()); - return makeResolver(descriptors).createAllInstancesInPlace(); - } - auto &last = descriptors.last(); - const auto originals = tryGetInstances(ServiceId{last.getImplementationTypeId(), last.getImplementationKey()}); - return originals ? std::make_optional(makeResolver(descriptors).createAllAliases(*originals)) : std::nullopt; + return lifetime.isSingleton() ? _root.getSingletons() : _scoped; } - INLINE ServiceInstanceList *ServiceInstanceProvider::createRestNonTransientAndGet( - const ServiceDescriptorList &descriptors, ServiceInstanceList &instances) + INLINE ServiceInstance ServiceInstanceProvider::tryCreateInstance(const ServiceDescriptor &descriptor) { - if (!descriptors.isAlias()) + if (descriptor.isAlias()) { - RequireDescriptor::nonTransient(descriptors.first()); - return &makeResolver(descriptors).createRestInstancesInPlace(instances); + return getAliasesCreator().tryCreate( + descriptor, tryGetInstance({descriptor.getImplementationTypeId(), descriptor.getImplementationKey()})); } - auto &last = descriptors.last(); - const auto originals = tryGetInstances(ServiceId{last.getImplementationTypeId(), last.getImplementationKey()}); - return originals ? &makeResolver(descriptors).createRestAliases(*originals, instances) : nullptr; + RequireDescriptor::nonTransient(descriptor); + return selectCreator(descriptor).createInPlace(descriptor); } - INLINE ServiceInstance ServiceInstanceProvider::tryCreateTransient(const ServiceDescriptorList &descriptors) + INLINE ServiceInstanceList ServiceInstanceProvider::tryCreateInstances(const ServiceDescriptorList &descriptors, + const std::size_t skipLast) { - if (!descriptors.isAlias()) + const auto &descriptor = descriptors.last(); + if (descriptor.isAlias()) { - RequireDescriptor::transient(descriptors.first()); - return makeResolver(descriptors).createInstance(); + return getAliasesCreator().tryCreateAll( + descriptors, + [this](const ServiceDescriptor &original) { + return tryGetInstances({original.getImplementationTypeId(), original.getImplementationKey()}); + }, + skipLast); } - auto &last = descriptors.last(); - auto alias = tryCreateInstance(ServiceId{last.getImplementationTypeId(), last.getImplementationKey()}); - alias.addCastOffset(last.getCastOffset()); - return alias; + RequireDescriptor::nonTransient(descriptor); + return selectCreator(descriptor).createAllInPlace(descriptors, skipLast); } - INLINE std::optional> ServiceInstanceProvider::tryCreateAllTransient( - const ServiceDescriptorList &descriptors) + INLINE ServiceInstance ServiceInstanceProvider::tryCreateTransientInstance(const ServiceDescriptor &descriptor) { - if (!descriptors.isAlias()) + if (descriptor.isAlias()) { - RequireDescriptor::transient(descriptors.first()); - return std::move(makeResolver(descriptors).createAllInstances().getInnerList()); + return getAliasesCreator().tryMap(descriptor, tryCreateInstance({descriptor.getImplementationTypeId(), + descriptor.getImplementationKey()})); } - auto &last = descriptors.last(); - auto aliases = tryCreateInstances(ServiceId{last.getImplementationTypeId(), last.getImplementationKey()}); - if (aliases && last.getCastOffset()) + RequireDescriptor::transient(descriptor); + return selectCreator(descriptor).create(descriptor); + } + + INLINE ServiceInstanceList + ServiceInstanceProvider::tryCreateTransientInstances(const ServiceDescriptorList &descriptors) + { + const auto &descriptor = descriptors.last(); + if (descriptor.isAlias()) { - aliases->forEach([&](ServiceInstance &instance) { instance.addCastOffset(last.getCastOffset()); }); + return getAliasesCreator().tryMapAll(descriptors, [this](const ServiceDescriptor &original) { + return tryCreateInstances({original.getImplementationTypeId(), original.getImplementationKey()}); + }); } - return aliases; + RequireDescriptor::transient(descriptor); + return selectCreator(descriptor).createAll(descriptors); } - INLINE ServiceInstancesResolver ServiceInstanceProvider::makeResolver(const ServiceDescriptorList &descriptors) + INLINE ServiceInstancesCreator &ServiceInstanceProvider::selectCreator(const ServiceDescriptor &descriptor) { - auto &creator = descriptors.getLifeTime().isSingleton() ? _root.getRootInstanceCreator() : getInstanceCreator(); - return ServiceInstancesResolver{creator, descriptors}; + return descriptor.getLifeTime().isSingleton() ? _root.getRootCreator() : getCreator(); } } // namespace sb::di::details diff --git a/Include/SevenBit/DI/Details/Core/Impl/ServiceInstanceProviderRoot.hpp b/Include/SevenBit/DI/Details/Core/Impl/ServiceInstanceProviderRoot.hpp index 8842a0e..f684349 100644 --- a/Include/SevenBit/DI/Details/Core/Impl/ServiceInstanceProviderRoot.hpp +++ b/Include/SevenBit/DI/Details/Core/Impl/ServiceInstanceProviderRoot.hpp @@ -22,26 +22,13 @@ namespace sb::di::details } } - INLINE const ServiceDescriptorsMap &ServiceInstanceProviderRoot::getDescriptorsMap() const - { - return _descriptorsMap; - } - - INLINE ServiceInstancesMap &ServiceInstanceProviderRoot::getSingletons() { return _singletons; } - - INLINE ServiceInstanceCreator &ServiceInstanceProviderRoot::getRootInstanceCreator() - { - return getInstanceCreator(); - } - INLINE void ServiceInstanceProviderRoot::prebuildSingletons() { - for (auto &[_, descriptors] : getDescriptorsMap()) + for (auto &[id, descriptors] : getDescriptorsMap()) { if (!descriptors.isAlias() && descriptors.getLifeTime().isSingleton()) { - tryRegisterAndGet({descriptors.getServiceTypeId(), descriptors.getServiceKey()}, descriptors, - tryCreateAllNonTransient(descriptors)); + tryGetInstances(id); } } } diff --git a/Include/SevenBit/DI/Details/Core/Impl/ServiceInstancesCreator.hpp b/Include/SevenBit/DI/Details/Core/Impl/ServiceInstancesCreator.hpp new file mode 100644 index 0000000..3182d04 --- /dev/null +++ b/Include/SevenBit/DI/Details/Core/Impl/ServiceInstancesCreator.hpp @@ -0,0 +1,63 @@ +#pragma once + +#include +#include + +#include "SevenBit/DI/LibraryConfig.hpp" + +#include "SevenBit/DI/Details/Core/ServiceInstancesCreator.hpp" +#include "SevenBit/DI/Details/Utils/Require.hpp" +#include "SevenBit/DI/Details/Utils/RequireDescriptor.hpp" +#include "SevenBit/DI/Details/Utils/RequireInstance.hpp" + +namespace sb::di::details +{ + INLINE ServiceInstance ServiceInstancesCreator::create(const ServiceDescriptor &descriptor) + { + return create(descriptor, false); + } + + INLINE ServiceInstanceList ServiceInstancesCreator::createAll(const ServiceDescriptorList &descriptors, + const std::size_t skipLast) + { + return createAll(descriptors, false, skipLast); + } + + INLINE ServiceInstance ServiceInstancesCreator::createInPlace(const ServiceDescriptor &descriptor) + { + return create(descriptor, true); + } + + INLINE ServiceInstanceList ServiceInstancesCreator::createAllInPlace(const ServiceDescriptorList &descriptors, + const std::size_t skipLast) + { + return createAll(descriptors, true, skipLast); + } + + INLINE ServiceInstanceList ServiceInstancesCreator::createAll(const ServiceDescriptorList &descriptors, + const bool inPlaceRequest, const std::size_t skipLast) + { + const auto size = descriptors.size(); + ServiceInstanceList instances{size}; + const auto take = skipLast <= size ? size - skipLast : 0; + descriptors.forEach([&](const ServiceDescriptor &descriptor, const std::size_t index) { + if (index < take) + { + instances.add(create(descriptor, inPlaceRequest)); + } + }); + return instances; + } + + INLINE ServiceInstance ServiceInstancesCreator::create(const ServiceDescriptor &descriptor, + const bool inPlaceRequest) + { + RequireDescriptor::nonAlias(descriptor); + auto &provider = *Require::notNullAndGet(_serviceProvider); + const auto &factory = *Require::notNullAndGet(descriptor.getImplementationFactory()); + auto _ = _circularDependencyGuard(descriptor.getImplementationTypeId()); + + return RequireInstance::validAndGet( + ServiceInstance{factory.createInstance(provider, inPlaceRequest), descriptor.getCastOffset()}); + } +} // namespace sb::di::details diff --git a/Include/SevenBit/DI/Details/Core/Impl/ServiceInstancesResolver.hpp b/Include/SevenBit/DI/Details/Core/Impl/ServiceInstancesResolver.hpp deleted file mode 100644 index d91e7c2..0000000 --- a/Include/SevenBit/DI/Details/Core/Impl/ServiceInstancesResolver.hpp +++ /dev/null @@ -1,149 +0,0 @@ -#pragma once - -#include -#include - -#include "SevenBit/DI/LibraryConfig.hpp" - -#include "SevenBit/DI/Details/Core/ServiceInstancesResolver.hpp" - -namespace sb::di::details -{ - INLINE ServiceInstancesResolver::ServiceInstancesResolver(ServiceInstanceCreator &creator, - const ServiceDescriptorList &descriptors) - : _creator(creator), _descriptors(descriptors) - { - } - - INLINE ServiceInstance ServiceInstancesResolver::createInstance() const { return createInstance(false); } - - INLINE ServiceInstanceList ServiceInstancesResolver::createOneInstance() const { return createOneInstance(false); } - - INLINE ServiceInstanceList ServiceInstancesResolver::createAllInstances() const - { - return createAllInstances(false); - } - - INLINE ServiceInstanceList &ServiceInstancesResolver::createRestInstances(ServiceInstanceList &instances) const - { - return createRestInstances(instances, false); - } - - INLINE ServiceInstance ServiceInstancesResolver::createInstanceInPlace() const { return createInstance(true); } - - INLINE ServiceInstanceList ServiceInstancesResolver::createOneInstanceInPlace() const - { - return createOneInstance(true); - } - - INLINE ServiceInstanceList ServiceInstancesResolver::createAllInstancesInPlace() const - { - return createAllInstances(true); - } - - INLINE ServiceInstanceList &ServiceInstancesResolver::createRestInstancesInPlace( - ServiceInstanceList &instances) const - { - return createRestInstances(instances, true); - } - - INLINE ServiceInstance ServiceInstancesResolver::createAlias(const ServiceInstance &original) const - { - return _creator.createInstanceAlias(_descriptors.last(), original); - } - - INLINE ServiceInstanceList ServiceInstancesResolver::createOneAlias(const ServiceInstance &original) const - { - return ServiceInstanceList{createAlias(original)}; - } - - INLINE ServiceInstanceList - ServiceInstancesResolver::createAllAliases(const OneOrList &originals) const - { - ServiceInstanceList instances{createAlias(originals.first())}; - if (const auto size = originals.size(); size > 1) - { - instances.reserve(size); - originals.forEach([&](const ServiceInstance &instance, const std::size_t index) { - if (index) // skip first - { - instances.add(createAlias(instance)); - } - }); - } - instances.seal(); - return instances; - } - - INLINE ServiceInstanceList &ServiceInstancesResolver::createRestAliases(const OneOrList &originals, - ServiceInstanceList &instances) const - { - if (const auto size = originals.size(); size > 1) - { - instances.reserve(size); - auto first = createAlias(originals.first()); - originals.forEach([&](const ServiceInstance &instance, const std::size_t index) { - if (index && index < size - 1) // skip first and last - { - instances.add(createAlias(instance)); - } - }); - instances.add(std::move(first)); - std::swap(instances.first(), instances.last()); - } - instances.seal(); - return instances; - } - - INLINE ServiceInstance ServiceInstancesResolver::createInstance(const bool inPlaceRequest) const - { - return _creator.createInstance(_descriptors.last(), inPlaceRequest); - } - - INLINE ServiceInstanceList ServiceInstancesResolver::createOneInstance(const bool inPlaceRequest) const - { - ServiceInstanceList instances{_creator.createInstance(_descriptors.last(), inPlaceRequest)}; - if (_descriptors.size() == 1) - { - instances.seal(); - } - return instances; - } - - INLINE ServiceInstanceList ServiceInstancesResolver::createAllInstances(const bool inPlaceRequest) const - { - ServiceInstanceList instances{_creator.createInstance(_descriptors.first(), inPlaceRequest)}; - if (const auto size = _descriptors.size(); size > 1) - { - instances.reserve(size); - _descriptors.getInnerList().forEach([&](const ServiceDescriptor &descriptor, const std::size_t index) { - if (index) // skip first - { - instances.add(_creator.createInstance(descriptor, inPlaceRequest)); - } - }); - } - instances.seal(); - return instances; - } - - INLINE ServiceInstanceList &ServiceInstancesResolver::createRestInstances(ServiceInstanceList &instances, - const bool inPlaceRequest) const - { - if (const auto size = _descriptors.size(); size > 1) - { - instances.reserve(size); - auto first = _creator.createInstance(_descriptors.first(), inPlaceRequest); - _descriptors.getInnerList().forEach([&](const ServiceDescriptor &descriptor, const std::size_t index) { - if (index && index < size - 1) // skip first and last - { - instances.add(_creator.createInstance(descriptor, inPlaceRequest)); - } - }); - instances.add(std::move(first)); - std::swap(instances.first(), instances.last()); - } - instances.seal(); - return instances; - } -} // namespace sb::di::details diff --git a/Include/SevenBit/DI/Details/Core/ServiceAliasesCreator.hpp b/Include/SevenBit/DI/Details/Core/ServiceAliasesCreator.hpp new file mode 100644 index 0000000..a7e7a9c --- /dev/null +++ b/Include/SevenBit/DI/Details/Core/ServiceAliasesCreator.hpp @@ -0,0 +1,54 @@ +#pragma once + +#include "SevenBit/DI/LibraryConfig.hpp" + +#include "SevenBit/DI/Details/Containers/ServiceDescriptorList.hpp" +#include "SevenBit/DI/Details/Containers/ServiceInstanceList.hpp" + +namespace sb::di::details +{ + class EXPORT ServiceAliasesCreator + { + public: + ServiceInstance tryCreate(const ServiceDescriptor &descriptor, const ServiceInstance *original) const; + + template + ServiceInstanceList tryCreateAll(const ServiceDescriptorList &descriptors, TResolver originalsResolver, + const std::size_t skipLast = 0) const + { + const auto size = descriptors.size(); + ServiceInstanceList instances{size}; + descriptors.forEach([&](const ServiceDescriptor &aliasDescriptor, const std::size_t index) { + const auto lastDescriptorSkip = index + 1 == size ? skipLast : 0; + tryCreateAll(instances, aliasDescriptor, originalsResolver(aliasDescriptor), lastDescriptorSkip); + }); + return instances; + } + + ServiceInstance tryMap(const ServiceDescriptor &descriptor, ServiceInstance &&original) const; + + template + ServiceInstanceList tryMapAll(const ServiceDescriptorList &descriptors, TResolver originalsResolver) const + { + ServiceInstanceList instances{descriptors.size()}; + descriptors.forEach([&](const ServiceDescriptor &aliasDescriptor) { + tryMapAll(instances, aliasDescriptor, originalsResolver(aliasDescriptor)); + }); + return instances; + } + + private: + void tryCreateAll(ServiceInstanceList &instances, const ServiceDescriptor &descriptor, + const OneOrList *originals, std::size_t skipLast = 0) const; + + void tryMapAll(ServiceInstanceList &instances, const ServiceDescriptor &descriptor, + OneOrList &&originals) const; + + [[nodiscard]] ServiceInstance create(const ServiceDescriptor &descriptor, + const ServiceInstance &original) const; + }; +} // namespace sb::di::details + +#ifdef _7BIT_DI_ADD_IMPL +#include "SevenBit/DI/Details/Core/Impl/ServiceAliasesCreator.hpp" +#endif diff --git a/Include/SevenBit/DI/Details/Core/ServiceInstanceCreator.hpp b/Include/SevenBit/DI/Details/Core/ServiceInstanceCreator.hpp deleted file mode 100644 index 81c53f6..0000000 --- a/Include/SevenBit/DI/Details/Core/ServiceInstanceCreator.hpp +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#include "SevenBit/DI/LibraryConfig.hpp" - -#include "SevenBit/DI/Details/Helpers/CircularDependencyGuard.hpp" -#include "SevenBit/DI/ServiceDescriptor.hpp" -#include "SevenBit/DI/ServiceInstance.hpp" -#include "SevenBit/DI/ServiceProvider.hpp" - -namespace sb::di::details -{ - class EXPORT ServiceInstanceCreator - { - ServiceProvider *_serviceProvider = nullptr; - CircularDependencyGuard _circularDependencyGuard; - - public: - void setServiceProvider(ServiceProvider &serviceProvider); - - ServiceInstance createInstance(const ServiceDescriptor &descriptor, bool inPlaceRequest); - - ServiceInstance createInstanceAlias(const ServiceDescriptor &descriptor, const ServiceInstance &instance); - - private: - static ServiceInstance createInstance(IServiceInstance::Ptr &&implementation, ptrdiff_t castOffset); - }; -} // namespace sb::di::details - -#ifdef _7BIT_DI_ADD_IMPL -#include "SevenBit/DI/Details/Core/Impl/ServiceInstanceCreator.hpp" -#endif diff --git a/Include/SevenBit/DI/Details/Core/ServiceInstanceProvider.hpp b/Include/SevenBit/DI/Details/Core/ServiceInstanceProvider.hpp index 73370a2..04ace73 100644 --- a/Include/SevenBit/DI/Details/Core/ServiceInstanceProvider.hpp +++ b/Include/SevenBit/DI/Details/Core/ServiceInstanceProvider.hpp @@ -8,8 +8,8 @@ #include "SevenBit/DI/Details/Containers/ServiceDescriptorList.hpp" #include "SevenBit/DI/Details/Containers/ServiceInstancesMap.hpp" #include "SevenBit/DI/Details/Core/IServiceInstanceProviderRoot.hpp" -#include "SevenBit/DI/Details/Core/ServiceInstanceCreator.hpp" -#include "SevenBit/DI/Details/Core/ServiceInstancesResolver.hpp" +#include "SevenBit/DI/Details/Core/ServiceAliasesCreator.hpp" +#include "SevenBit/DI/Details/Core/ServiceInstancesCreator.hpp" #include "SevenBit/DI/IServiceInstanceProvider.hpp" #include "SevenBit/DI/ServiceProviderOptions.hpp" @@ -18,7 +18,8 @@ namespace sb::di::details class EXPORT ServiceInstanceProvider : public IServiceInstanceProvider { ServiceProviderOptions _options; - ServiceInstanceCreator _instanceCreator; + ServiceInstancesCreator _instancesCreator; + ServiceAliasesCreator _aliasesCreator; IServiceInstanceProviderRoot &_root; ServiceInstancesMap _scoped; @@ -59,7 +60,7 @@ namespace sb::di::details { return tryCreateInstance(ServiceId{serviceTypeId}); } - std::optional> tryCreateInstances(const TypeId serviceTypeId) override + OneOrList tryCreateInstances(const TypeId serviceTypeId) override { return tryCreateInstances(ServiceId{serviceTypeId}); } @@ -96,8 +97,8 @@ namespace sb::di::details { return tryCreateInstance(ServiceId{serviceTypeId, serviceKey}); } - std::optional> tryCreateKeyedInstances(const TypeId serviceTypeId, - const std::string_view serviceKey) override + OneOrList tryCreateKeyedInstances(const TypeId serviceTypeId, + const std::string_view serviceKey) override { return tryCreateInstances(ServiceId{serviceTypeId, serviceKey}); } @@ -120,31 +121,30 @@ namespace sb::di::details ServiceInstance createInstance(const ServiceId &id); ServiceInstance tryCreateInstance(const ServiceId &id); - std::optional> tryCreateInstances(const ServiceId &id); + OneOrList tryCreateInstances(const ServiceId &id); ServiceInstance createInstanceInPlace(const ServiceId &id); ServiceInstance tryCreateInstanceInPlace(const ServiceId &id); void clear() { _scoped.clear(); } - ServiceInstanceList *findRegisteredInstances(const ServiceId &id); + ServiceInstanceList *findInstances(const ServiceId &id); - [[nodiscard]] const ServiceDescriptorList *findDescriptors(const ServiceId &id, bool transient) const; + [[nodiscard]] const ServiceDescriptorList *findDescriptors(const ServiceId &id) const; + [[nodiscard]] const ServiceDescriptorList *findTransientDescriptors(const ServiceId &id) const; - ServiceInstanceList *tryRegisterAndGet(const ServiceId &id, const ServiceDescriptorList &descriptors, - std::optional &&instances); + [[nodiscard]] ServiceLifeTime getLifeTime(const ServiceDescriptor &descriptor) const; + ServiceInstancesMap &getInstancesMap(ServiceLifeTime lifetime); - std::optional tryCreateNonTransient(const ServiceDescriptorList &descriptors); - std::optional tryCreateAllNonTransient(const ServiceDescriptorList &descriptors); - ServiceInstanceList *createRestNonTransientAndGet(const ServiceDescriptorList &descriptors, - ServiceInstanceList &instances); + ServiceInstance tryCreateInstance(const ServiceDescriptor &descriptor); + ServiceInstanceList tryCreateInstances(const ServiceDescriptorList &descriptors, std::size_t skipLast = 0); - ServiceInstance tryCreateTransient(const ServiceDescriptorList &descriptors); - std::optional> tryCreateAllTransient(const ServiceDescriptorList &descriptors); + ServiceInstance tryCreateTransientInstance(const ServiceDescriptor &descriptor); + ServiceInstanceList tryCreateTransientInstances(const ServiceDescriptorList &descriptors); - ServiceInstancesResolver makeResolver(const ServiceDescriptorList &descriptors); - - ServiceInstanceCreator &getInstanceCreator() { return _instanceCreator; } + ServiceInstancesCreator &selectCreator(const ServiceDescriptor &descriptor); + ServiceAliasesCreator &getAliasesCreator() { return _aliasesCreator; } + ServiceInstancesCreator &getCreator() { return _instancesCreator; } }; } // namespace sb::di::details diff --git a/Include/SevenBit/DI/Details/Core/ServiceInstanceProviderRoot.hpp b/Include/SevenBit/DI/Details/Core/ServiceInstanceProviderRoot.hpp index 4cb956e..d51ac52 100644 --- a/Include/SevenBit/DI/Details/Core/ServiceInstanceProviderRoot.hpp +++ b/Include/SevenBit/DI/Details/Core/ServiceInstanceProviderRoot.hpp @@ -31,11 +31,11 @@ namespace sb::di::details void init(ServiceProvider &serviceProvider) override; - [[nodiscard]] const ServiceDescriptorsMap &getDescriptorsMap() const override; + [[nodiscard]] const ServiceDescriptorsMap &getDescriptorsMap() const override { return _descriptorsMap; } - ServiceInstancesMap &getSingletons() override; + ServiceInstancesMap &getSingletons() override { return _singletons; } - ServiceInstanceCreator &getRootInstanceCreator() override; + ServiceInstancesCreator &getRootCreator() override { return getCreator(); } private: void prebuildSingletons(); diff --git a/Include/SevenBit/DI/Details/Core/ServiceInstancesCreator.hpp b/Include/SevenBit/DI/Details/Core/ServiceInstancesCreator.hpp new file mode 100644 index 0000000..fc2f1c2 --- /dev/null +++ b/Include/SevenBit/DI/Details/Core/ServiceInstancesCreator.hpp @@ -0,0 +1,34 @@ +#pragma once + +#include "SevenBit/DI/LibraryConfig.hpp" + +#include "SevenBit/DI/Details/Containers/ServiceDescriptorList.hpp" +#include "SevenBit/DI/Details/Containers/ServiceInstanceList.hpp" +#include "SevenBit/DI/Details/Helpers/CircularDependencyGuard.hpp" + +namespace sb::di::details +{ + class EXPORT ServiceInstancesCreator + { + ServiceProvider *_serviceProvider = nullptr; + CircularDependencyGuard _circularDependencyGuard; + + public: + void setServiceProvider(ServiceProvider &serviceProvider) { _serviceProvider = &serviceProvider; } + + ServiceInstance create(const ServiceDescriptor &descriptor); + ServiceInstanceList createAll(const ServiceDescriptorList &descriptors, std::size_t skipLast = 0); + + ServiceInstance createInPlace(const ServiceDescriptor &descriptor); + ServiceInstanceList createAllInPlace(const ServiceDescriptorList &descriptors, std::size_t skipLast = 0); + + private: + ServiceInstance create(const ServiceDescriptor &descriptor, bool inPlaceRequest); + ServiceInstanceList createAll(const ServiceDescriptorList &descriptors, bool inPlaceRequest, + std::size_t skipLast); + }; +} // namespace sb::di::details + +#ifdef _7BIT_DI_ADD_IMPL +#include "SevenBit/DI/Details/Core/Impl/ServiceInstancesCreator.hpp" +#endif diff --git a/Include/SevenBit/DI/Details/Core/ServiceInstancesResolver.hpp b/Include/SevenBit/DI/Details/Core/ServiceInstancesResolver.hpp deleted file mode 100644 index ce707c9..0000000 --- a/Include/SevenBit/DI/Details/Core/ServiceInstancesResolver.hpp +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once - -#include "SevenBit/DI/LibraryConfig.hpp" - -#include "SevenBit/DI/Details/Containers/ServiceDescriptorList.hpp" -#include "SevenBit/DI/Details/Containers/ServiceInstanceList.hpp" -#include "SevenBit/DI/Details/Core/ServiceInstanceCreator.hpp" - -namespace sb::di::details -{ - class EXPORT ServiceInstancesResolver - { - ServiceInstanceCreator &_creator; - const ServiceDescriptorList &_descriptors; - - public: - ServiceInstancesResolver(ServiceInstanceCreator &creator, const ServiceDescriptorList &descriptors); - - [[nodiscard]] ServiceInstance createInstance() const; - [[nodiscard]] ServiceInstanceList createOneInstance() const; - [[nodiscard]] ServiceInstanceList createAllInstances() const; - ServiceInstanceList &createRestInstances(ServiceInstanceList &instances) const; - - [[nodiscard]] ServiceInstance createInstanceInPlace() const; - [[nodiscard]] ServiceInstanceList createOneInstanceInPlace() const; - [[nodiscard]] ServiceInstanceList createAllInstancesInPlace() const; - ServiceInstanceList &createRestInstancesInPlace(ServiceInstanceList &instances) const; - - [[nodiscard]] ServiceInstance createAlias(const ServiceInstance &original) const; - [[nodiscard]] ServiceInstanceList createOneAlias(const ServiceInstance &original) const; - [[nodiscard]] ServiceInstanceList createAllAliases(const OneOrList &originals) const; - [[nodiscard]] ServiceInstanceList &createRestAliases(const OneOrList &originals, - ServiceInstanceList &instances) const; - - private: - [[nodiscard]] ServiceInstance createInstance(bool inPlaceRequest) const; - [[nodiscard]] ServiceInstanceList createOneInstance(bool inPlaceRequest) const; - [[nodiscard]] ServiceInstanceList createAllInstances(bool inPlaceRequest) const; - ServiceInstanceList &createRestInstances(ServiceInstanceList &instances, bool inPlaceRequest) const; - }; -} // namespace sb::di::details - -#ifdef _7BIT_DI_ADD_IMPL -#include "SevenBit/DI/Details/Core/Impl/ServiceInstancesResolver.hpp" -#endif diff --git a/Include/SevenBit/DI/Details/Utils/Cast.hpp b/Include/SevenBit/DI/Details/Utils/Cast.hpp index 43108af..b7a43ad 100644 --- a/Include/SevenBit/DI/Details/Utils/Cast.hpp +++ b/Include/SevenBit/DI/Details/Utils/Cast.hpp @@ -8,14 +8,14 @@ namespace sb::di::details { struct Cast { - template static constexpr intptr_t getCastOffset() + template static constexpr ptrdiff_t getCastOffset() { auto implementation = reinterpret_cast(std::numeric_limits::max() / 2); auto service = static_cast(implementation); return reinterpret_cast(service) - reinterpret_cast(implementation); }; - static void *applyCastOffset(void *ptr, const intptr_t offset) + static void *applyCastOffset(void *ptr, const ptrdiff_t offset) { const auto casted = reinterpret_cast(ptr) + offset; return reinterpret_cast(casted); diff --git a/Include/SevenBit/DI/Export.hpp b/Include/SevenBit/DI/Export.hpp index 37c00c8..2a5948a 100644 --- a/Include/SevenBit/DI/Export.hpp +++ b/Include/SevenBit/DI/Export.hpp @@ -32,4 +32,4 @@ #else // Static or header only lib #define EXPORT -#endif \ No newline at end of file +#endif diff --git a/Include/SevenBit/DI/IServiceInstanceProvider.hpp b/Include/SevenBit/DI/IServiceInstanceProvider.hpp index 9d446f7..d9d5015 100644 --- a/Include/SevenBit/DI/IServiceInstanceProvider.hpp +++ b/Include/SevenBit/DI/IServiceInstanceProvider.hpp @@ -98,14 +98,14 @@ namespace sb::di * @brief Creates service instances * @details If service was not registered or was registered as scoped/singleton, method returns null option */ - virtual std::optional> tryCreateInstances(TypeId serviceTypeId) = 0; + virtual OneOrList tryCreateInstances(TypeId serviceTypeId) = 0; /** * @brief Creates service instances * @details If service was not registered or was registered as scoped/singleton, method returns null option */ - virtual std::optional> tryCreateKeyedInstances(TypeId serviceTypeId, - std::string_view serviceKey) = 0; + virtual OneOrList tryCreateKeyedInstances(TypeId serviceTypeId, + std::string_view serviceKey) = 0; /** * @brief Creates service instance in place, might throw exception diff --git a/Include/SevenBit/DI/Impl/ServiceCollection.hpp b/Include/SevenBit/DI/Impl/ServiceCollection.hpp index 3254c43..45f60d2 100644 --- a/Include/SevenBit/DI/Impl/ServiceCollection.hpp +++ b/Include/SevenBit/DI/Impl/ServiceCollection.hpp @@ -20,42 +20,6 @@ namespace sb::di return std::make_unique(std::move(instanceProvider)); } - INLINE std::vector &ServiceCollection::getInnerVector() { return _serviceDescriptors; } - INLINE const std::vector &ServiceCollection::getInnerVector() const - { - return _serviceDescriptors; - } - - INLINE ServiceDescriptor &ServiceCollection::at(const std::size_t index) { return _serviceDescriptors.at(index); } - INLINE const ServiceDescriptor &ServiceCollection::at(const std::size_t index) const - { - return _serviceDescriptors.at(index); - } - - INLINE ServiceDescriptor &ServiceCollection::first() { return at(0); } - INLINE const ServiceDescriptor &ServiceCollection::first() const { return at(0); } - - INLINE ServiceDescriptor &ServiceCollection::last() { return at(size() - 1); } - INLINE const ServiceDescriptor &ServiceCollection::last() const { return at(size() - 1); } - - INLINE ServiceDescriptor &ServiceCollection::operator[](const std::size_t index) { return at(index); } - INLINE const ServiceDescriptor &ServiceCollection::operator[](const std::size_t index) const { return at(index); } - - INLINE std::size_t ServiceCollection::maxSize() const { return _serviceDescriptors.max_size(); } - - INLINE std::size_t ServiceCollection::size() const { return _serviceDescriptors.size(); } - INLINE std::size_t ServiceCollection::count() const { return size(); } - - INLINE bool ServiceCollection::empty() const { return _serviceDescriptors.empty(); } - - INLINE std::size_t ServiceCollection::capacity() const { return _serviceDescriptors.capacity(); } - - INLINE void ServiceCollection::reserve(const std::size_t space) { _serviceDescriptors.reserve(space); } - - INLINE void ServiceCollection::shrinkToFit() { _serviceDescriptors.shrink_to_fit(); } - - INLINE void ServiceCollection::clear() { _serviceDescriptors.clear(); } - INLINE bool ServiceCollection::contains(const TypeId serviceTypeId) const { return containsIf( @@ -88,11 +52,6 @@ namespace sb::di }); } - INLINE ServiceCollection::Iterator ServiceCollection::insert(const ConstIterator pos, ServiceDescriptor descriptor) - { - return _serviceDescriptors.insert(pos, std::move(descriptor)); - } - INLINE ServiceCollection &ServiceCollection::add(ServiceDescriptor descriptor) { _serviceDescriptors.push_back(std::move(descriptor)); @@ -109,25 +68,6 @@ namespace sb::di return *this; } - INLINE ServiceCollection::Iterator ServiceCollection::remove(const Iterator pos) - { - return _serviceDescriptors.erase(pos); - } - INLINE ServiceCollection::Iterator ServiceCollection::remove(const ConstIterator pos) - { - return _serviceDescriptors.erase(pos); - } - - INLINE ServiceCollection::Iterator ServiceCollection::removeRange(const Iterator begin, const Iterator end) - { - return _serviceDescriptors.erase(begin, end); - } - INLINE ServiceCollection::Iterator ServiceCollection::removeRange(const ConstIterator begin, - const ConstIterator end) - { - return _serviceDescriptors.erase(begin, end); - } - INLINE std::size_t ServiceCollection::removeAll(const TypeId serviceTypeId) { return removeIf( @@ -159,15 +99,4 @@ namespace sb::di *descriptor.getServiceKey() == serviceKey; }); } - - INLINE void ServiceCollection::pop() { _serviceDescriptors.pop_back(); } - - INLINE bool operator==(const ServiceCollection &lhs, const ServiceCollection &rhs) - { - return lhs._serviceDescriptors == rhs._serviceDescriptors; - } - INLINE bool operator!=(const ServiceCollection &lhs, const ServiceCollection &rhs) - { - return lhs._serviceDescriptors != rhs._serviceDescriptors; - } } // namespace sb::di diff --git a/Include/SevenBit/DI/OneOrList.hpp b/Include/SevenBit/DI/OneOrList.hpp index d00d91a..5f126d1 100644 --- a/Include/SevenBit/DI/OneOrList.hpp +++ b/Include/SevenBit/DI/OneOrList.hpp @@ -10,12 +10,18 @@ namespace sb::di { + template class OneOrList { - std::variant> _variant{}; + struct Uninitialized + { + }; + + std::variant> _variant{}; public: - explicit OneOrList(const std::size_t size) : _variant(std::vector{}) { reserve(size); } + OneOrList() = default; + explicit OneOrList(const std::size_t size) { reserve(size); } explicit OneOrList(T &&mainElement) : _variant(std::move(mainElement)) {} OneOrList(const OneOrList &) = delete; @@ -24,14 +30,13 @@ namespace sb::di OneOrList &operator=(const OneOrList &) = delete; OneOrList &operator=(OneOrList &&other) noexcept = default; + [[nodiscard]] bool isUninitialized() const { return std::holds_alternative(_variant); } + [[nodiscard]] bool isSingle() const { return std::holds_alternative(_variant); } [[nodiscard]] bool isList() const { return std::holds_alternative>(_variant); } std::vector &getAsList() { return std::get>(_variant); } const std::vector &getAsList() const { return std::get>(_variant); } - std::variant> &getVariant() { return _variant; } - const std::variant> &getVariant() const { return _variant; } - T &getAsSingle() { return std::get(_variant); } const T &getAsSingle() const { return std::get(_variant); } @@ -41,10 +46,41 @@ namespace sb::di T *tryGetAsSingle() { return std::get_if(&_variant); } const T *tryGetAsSingle() const { return std::get_if(&_variant); } + explicit operator bool() const { return !isUninitialized(); } + void add(T &&element) { - tryConvertToList(); - getAsList().emplace_back(std::move(element)); + if (isUninitialized()) + { + _variant = std::move(element); + } + else if (auto list = tryGetAsList()) + { + list->emplace_back(std::move(element)); + } + else + { + tryConvertToList(); + getAsList().emplace_back(std::move(element)); + } + } + + void addList(OneOrList &&other) + { + if (auto list = other.tryGetAsList()) + { + tryConvertToList(); + auto &thisList = getAsList(); + thisList.reserve(thisList.size() + list->size()); + for (auto &element : *list) + { + thisList.emplace_back(std::move(element)); + } + } + else if (auto single = other.tryGetAsSingle()) + { + add(std::move(*single)); + } } T &first() @@ -72,9 +108,20 @@ namespace sb::di T &operator[](std::size_t index) { auto single = tryGetAsSingle(); - return single ? *single : getAsList().at(index); + return single ? *single : getAsList()[index]; } const T &operator[](std::size_t index) const + { + auto single = tryGetAsSingle(); + return single ? *single : getAsList()[index]; + } + + T &at(std::size_t index) + { + auto single = tryGetAsSingle(); + return single ? *single : getAsList().at(index); + } + const T &at(std::size_t index) const { auto single = tryGetAsSingle(); return single ? *single : getAsList().at(index); @@ -82,16 +129,23 @@ namespace sb::di [[nodiscard]] std::size_t size() const { + if (isSingle()) + { + return 1; + } auto list = tryGetAsList(); - return list ? list->size() : 1; + return list ? list->size() : 0; } [[nodiscard]] bool empty() const { return !size(); } void reserve(std::size_t newCapacity) { - tryConvertToList(); - getAsList().reserve(newCapacity); + if (newCapacity > 1) + { + tryConvertToList(); + getAsList().reserve(newCapacity); + } } void shrink() @@ -102,31 +156,47 @@ namespace sb::di } } + void clear() + { + if (auto list = tryGetAsList()) + { + list->clear(); + } + else + { + _variant = Uninitialized{}; + } + } + template void forEach(TFunc fcn) { - if (auto instance = tryGetAsSingle()) + if (auto single = tryGetAsSingle()) { - callFcn(fcn, *instance, 0); - return; + callFcn(fcn, *single, 0); } - std::size_t index = 0; - for (auto &instance : getAsList()) + else if (auto list = tryGetAsList()) { - callFcn(fcn, instance, index++); + std::size_t index = 0; + for (auto &instance : *list) + { + callFcn(fcn, instance, index++); + } } } template void forEach(TFunc fcn) const { - if (const auto instance = tryGetAsSingle()) + if (const auto single = tryGetAsSingle()) { - callFcn(fcn, *instance, 0); - return; + callFcn(fcn, *single, 0); } - std::size_t index = 0; - for (const auto &instance : getAsList()) + else if (auto list = tryGetAsList()) { - callFcn(fcn, instance, index++); + std::size_t index = 0; + for (auto &instance : *list) + { + callFcn(fcn, instance, index++); + } } } @@ -149,11 +219,18 @@ namespace sb::di private: void tryConvertToList() { - if (auto single = tryGetAsSingle()) + if (!isList()) { - std::vector vec; - vec.emplace_back(std::move(*single)); - _variant = std::move(vec); + if (auto single = tryGetAsSingle()) + { + std::vector vec; + vec.emplace_back(std::move(*single)); + _variant = std::move(vec); + } + else + { + _variant = std::vector{}; + } } } diff --git a/Include/SevenBit/DI/ServiceCollection.hpp b/Include/SevenBit/DI/ServiceCollection.hpp index 6330a6a..502f5b8 100644 --- a/Include/SevenBit/DI/ServiceCollection.hpp +++ b/Include/SevenBit/DI/ServiceCollection.hpp @@ -79,102 +79,105 @@ namespace sb::di /** * @brief Returns inner vector container */ - std::vector &getInnerVector(); + std::vector &getInnerVector() { return _serviceDescriptors; } /** * @brief Returns inner vector container */ - [[nodiscard]] const std::vector &getInnerVector() const; + [[nodiscard]] const std::vector &getInnerVector() const { return _serviceDescriptors; } /** * @brief Returns service descriptor at giver position * @details might throw exception * @throws std::out_of_range if index >= size() */ - ServiceDescriptor &at(std::size_t index); + ServiceDescriptor &at(const std::size_t index) { return _serviceDescriptors.at(index); } /** * @brief Returns service descriptor at giver position * @details might throw exception * @throws std::out_of_range if index >= size() */ - [[nodiscard]] const ServiceDescriptor &at(std::size_t index) const; + [[nodiscard]] const ServiceDescriptor &at(const std::size_t index) const + { + return _serviceDescriptors.at(index); + } /** * @brief Returns first descriptor * @details might throw exception * @throws std::out_of_range if empty() */ - ServiceDescriptor &first(); + ServiceDescriptor &first() { return at(0); } /** * @brief Returns first descriptor * @details might throw exception * @throws std::out_of_range if empty() */ - [[nodiscard]] const ServiceDescriptor &first() const; + [[nodiscard]] const ServiceDescriptor &first() const { return at(0); } /** * @brief Returns last descriptor * @details might throw exception * @throws std::out_of_range if empty() */ - ServiceDescriptor &last(); + ServiceDescriptor &last() { return at(size() - 1); } /** * @brief Returns last descriptor * @details might throw exception * @throws std::out_of_range if empty() */ - [[nodiscard]] const ServiceDescriptor &last() const; + [[nodiscard]] const ServiceDescriptor &last() const { return at(size() - 1); } /** * @brief Returns service descriptor at giver position * @details might throw exception * @throws std::out_of_range if index >= size() */ - ServiceDescriptor &operator[](std::size_t index); + ServiceDescriptor &operator[](const std::size_t index) { return _serviceDescriptors[index]; } /** * @brief Returns service descriptor at giver position * @details might throw exception * @throws std::out_of_range if index >= size() */ - const ServiceDescriptor &operator[](std::size_t index) const; + const ServiceDescriptor &operator[](const std::size_t index) const { return _serviceDescriptors[index]; } /** * @brief Returns the maximum possible number of stored descriptors */ - [[nodiscard]] std::size_t maxSize() const; + [[nodiscard]] std::size_t maxSize() const { return _serviceDescriptors.max_size(); } /** * @brief Returns number of stored descriptors */ - [[nodiscard]] std::size_t size() const; + [[nodiscard]] std::size_t size() const { return _serviceDescriptors.size(); } /** * @brief Returns number of stored descriptors */ - [[nodiscard]] std::size_t count() const; + [[nodiscard]] std::size_t count() const { return size(); } /** * @brief Returns true if there are no descriptors */ - [[nodiscard]] bool empty() const; + [[nodiscard]] bool empty() const { return _serviceDescriptors.empty(); } /** * @brief Returns capacity */ - [[nodiscard]] std::size_t capacity() const; + [[nodiscard]] std::size_t capacity() const { return _serviceDescriptors.capacity(); } /** * @brief Reserves space for descriptors */ - void reserve(std::size_t space); + void reserve(const std::size_t space) { _serviceDescriptors.reserve(space); } /** * @brief Shrinks to fit current size of descriptors */ - void shrinkToFit(); + void shrinkToFit() { _serviceDescriptors.shrink_to_fit(); } /** * @brief Removes all descriptors */ - void clear(); + void clear() { _serviceDescriptors.clear(); } /** * @brief Find first descriptor meeting TPred requirement @@ -283,7 +286,10 @@ namespace sb::di * @brief Inserts descriptor before giver iterator * @details Returns iterator pointing to the inserted */ - Iterator insert(ConstIterator pos, ServiceDescriptor descriptor); + Iterator insert(ConstIterator pos, ServiceDescriptor descriptor) + { + return _serviceDescriptors.insert(pos, std::move(descriptor)); + } /** * @brief Adds descriptor to the end of list @@ -315,25 +321,25 @@ namespace sb::di * @brief Removes descriptor with given iterator * @details Returns iterator following the last removed element */ - Iterator remove(Iterator pos); + Iterator remove(Iterator pos) { return _serviceDescriptors.erase(pos); } /** * @brief Removes descriptor with given iterator * @details Returns iterator following the last removed element */ - Iterator remove(ConstIterator pos); + Iterator remove(ConstIterator pos) { return _serviceDescriptors.erase(pos); } /** * @brief Removes descriptors between given iterators * @details Returns iterator following the last removed element */ - Iterator removeRange(Iterator begin, Iterator end); + Iterator removeRange(Iterator begin, Iterator end) { return _serviceDescriptors.erase(begin, end); } /** * @brief Removes descriptors between given iterators * @details Returns iterator following the last removed element */ - Iterator removeRange(ConstIterator begin, ConstIterator end); + Iterator removeRange(ConstIterator begin, ConstIterator end) { return _serviceDescriptors.erase(begin, end); } /** * @brief Removes all descriptors meeting TPred requirement @@ -437,7 +443,7 @@ namespace sb::di /** * @brief Removes last descriptor */ - void pop(); + void pop() { _serviceDescriptors.pop_back(); } /** * @brief Adds service descriptor @@ -1048,8 +1054,14 @@ namespace sb::di std::make_unique(std::move(serviceAliasKey)), nullptr)); } - friend bool operator==(const ServiceCollection &lhs, const ServiceCollection &rhs); - friend bool operator!=(const ServiceCollection &lhs, const ServiceCollection &rhs); + friend bool operator==(const ServiceCollection &lhs, const ServiceCollection &rhs) + { + return lhs._serviceDescriptors == rhs._serviceDescriptors; + } + friend bool operator!=(const ServiceCollection &lhs, const ServiceCollection &rhs) + { + return lhs._serviceDescriptors != rhs._serviceDescriptors; + } }; } // namespace sb::di diff --git a/Include/SevenBit/DI/ServiceProvider.hpp b/Include/SevenBit/DI/ServiceProvider.hpp index 867aa61..83c8345 100644 --- a/Include/SevenBit/DI/ServiceProvider.hpp +++ b/Include/SevenBit/DI/ServiceProvider.hpp @@ -367,14 +367,11 @@ namespace sb::di */ template std::vector> createServices() { - if (auto optInstances = getInstanceProvider().tryCreateInstances(typeid(TService))) - { - return optInstances->map([&](ServiceInstance &instance) { - details::RequireInstance::valid(instance); - return instance.moveOutAsUniquePtr(); - }); - } - return {}; + auto instances = getInstanceProvider().tryCreateInstances(typeid(TService)); + return instances.map([&](ServiceInstance &instance) { + details::RequireInstance::valid(instance); + return instance.moveOutAsUniquePtr(); + }); } /** @@ -395,14 +392,11 @@ namespace sb::di template std::vector> createKeyedServices(const std::string_view serviceKey) { - if (auto optInstances = getInstanceProvider().tryCreateKeyedInstances(typeid(TService), serviceKey)) - { - return optInstances->map([&](ServiceInstance &instance) { - details::RequireInstance::valid(instance); - return instance.moveOutAsUniquePtr(); - }); - } - return {}; + auto instances = getInstanceProvider().tryCreateKeyedInstances(typeid(TService), serviceKey); + return instances.map([&](ServiceInstance &instance) { + details::RequireInstance::valid(instance); + return instance.moveOutAsUniquePtr(); + }); } }; } // namespace sb::di diff --git a/README.md b/README.md index c2a2df3..54db97f 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ include(FetchContent) FetchContent_Declare( 7bitDI GIT_REPOSITORY https://github.com/7bitcoder/7bitDI.git - GIT_TAG v3.1.0 + GIT_TAG v3.2.0 ) FetchContent_MakeAvailable(7bitDI) @@ -78,7 +78,7 @@ Download and install A [Conan](https://conan.io/), and create conanfile.txt in t ``` [requires] -7bitdi/3.1.0 +7bitdi/3.2.0 ``` change the version to newer if available, then run the command: diff --git a/SingleHeader/CMakeLists.txt b/SingleHeader/CMakeLists.txt index 28930f3..b0e7a08 100644 --- a/SingleHeader/CMakeLists.txt +++ b/SingleHeader/CMakeLists.txt @@ -4,14 +4,12 @@ set(_7BIT_DI_SINGLE_IN ${CMAKE_CURRENT_SOURCE_DIR}/SevenBitDI.hpp.in) set(_7BIT_DI_SINGLE_OUT ${CMAKE_CURRENT_BINARY_DIR}/SevenBitDI.hpp) add_custom_command(OUTPUT ${_7BIT_DI_SINGLE_OUT} - COMMAND - ${QUOM_EXECUTABLE} ${_7BIT_DI_SINGLE_IN} ${_7BIT_DI_SINGLE_OUT} -I ${_7BIT_DI_INCLUDE_DIR} - DEPENDS - ${_7BIT_DI_ALL_HEADERS} - COMMENT "Generating single header with Quom") + COMMAND + ${QUOM_EXECUTABLE} ${_7BIT_DI_SINGLE_IN} ${_7BIT_DI_SINGLE_OUT} -I ${_7BIT_DI_INCLUDE_DIR} + COMMENT "Generating single header with Quom") add_custom_target(GenerateSingleHeader - ALL DEPENDS - ${_7BIT_DI_SINGLE_OUT} - ${_7BIT_DI_MAIN_HEADER} + ALL DEPENDS + ${_7BIT_DI_SINGLE_OUT} + ${_7BIT_DI_MAIN_HEADER} ) diff --git a/SingleHeader/SevenBitDI.hpp.in b/SingleHeader/SevenBitDI.hpp.in index eedcaef..aebcb49 100644 --- a/SingleHeader/SevenBitDI.hpp.in +++ b/SingleHeader/SevenBitDI.hpp.in @@ -2,4 +2,4 @@ #define _7BIT_DI_HEADER_ONLY_LIB -#include "SevenBit/DI.hpp" \ No newline at end of file +#include "SevenBit/DI.hpp" diff --git a/Source/ConfigCheck.hpp b/Source/ConfigCheck.hpp index 2693351..6579ecf 100644 --- a/Source/ConfigCheck.hpp +++ b/Source/ConfigCheck.hpp @@ -1,6 +1,6 @@ #pragma once -#include "SevenBit/DI/LibraryConfig.hpp" +#include #ifndef _7BIT_DI_ADD_IMPL #define _7BIT_DI_ADD_IMPL @@ -10,4 +10,4 @@ #undef INLINE #endif -#define INLINE \ No newline at end of file +#define INLINE diff --git a/Source/Source.cpp b/Source/Source.cpp index 89a70f1..32a7f14 100644 --- a/Source/Source.cpp +++ b/Source/Source.cpp @@ -1,17 +1,16 @@ #include "ConfigCheck.hpp" -#include "SevenBit/DI/Details/Containers/Impl/ServiceDescriptorList.hpp" -#include "SevenBit/DI/Details/Containers/Impl/ServiceDescriptorsMap.hpp" -#include "SevenBit/DI/Details/Containers/Impl/ServiceInstanceList.hpp" -#include "SevenBit/DI/Details/Containers/Impl/ServiceInstancesMap.hpp" -#include "SevenBit/DI/Details/Core/Impl/ServiceInstanceCreator.hpp" -#include "SevenBit/DI/Details/Core/Impl/ServiceInstanceProvider.hpp" -#include "SevenBit/DI/Details/Core/Impl/ServiceInstanceProviderRoot.hpp" -#include "SevenBit/DI/Details/Core/Impl/ServiceInstancesResolver.hpp" -#include "SevenBit/DI/Details/Helpers/Impl/CircularDependencyGuard.hpp" -#include "SevenBit/DI/Details/Helpers/Impl/ScopedGuard.hpp" -#include "SevenBit/DI/Details/Utils/Impl/RequireDescriptor.hpp" -#include "SevenBit/DI/Details/Utils/Impl/RequireInstance.hpp" -#include "SevenBit/DI/Impl/Exceptions.hpp" -#include "SevenBit/DI/Impl/ServiceCollection.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/Tests/Helpers/Classes/Complex.hpp b/Tests/Helpers/Classes/Complex.hpp index 0c35b26..c86bbd4 100644 --- a/Tests/Helpers/Classes/Complex.hpp +++ b/Tests/Helpers/Classes/Complex.hpp @@ -5,8 +5,8 @@ #include -#include "SevenBit/DI/ServiceCollection.hpp" -#include "SevenBit/DI/ServiceProvider.hpp" +#include +#include struct ITestComplexClass1 { diff --git a/Tests/Helpers/Classes/Dependencies.hpp b/Tests/Helpers/Classes/Dependencies.hpp index 8d14641..3c8ac1a 100644 --- a/Tests/Helpers/Classes/Dependencies.hpp +++ b/Tests/Helpers/Classes/Dependencies.hpp @@ -3,7 +3,7 @@ #include #include -#include "SevenBit/DI/ServiceProvider.hpp" +#include struct TestDependencyClass { diff --git a/Tests/Helpers/Classes/Legion.hpp b/Tests/Helpers/Classes/Legion.hpp index 525d21e..5eb3516 100644 --- a/Tests/Helpers/Classes/Legion.hpp +++ b/Tests/Helpers/Classes/Legion.hpp @@ -1,10 +1,10 @@ #pragma once -#include "SevenBit/DI/ServiceCollection.hpp" +#include template class Legion { - int data[25] = {0}; // 100b + char data[100] = {0}; // 100b public: Legion() = default; diff --git a/Tests/Helpers/Mocks/ServiceInstanceProviderMock.hpp b/Tests/Helpers/Mocks/ServiceInstanceProviderMock.hpp index 693e1e4..dc315cf 100644 --- a/Tests/Helpers/Mocks/ServiceInstanceProviderMock.hpp +++ b/Tests/Helpers/Mocks/ServiceInstanceProviderMock.hpp @@ -2,7 +2,7 @@ #include -#include "SevenBit/DI/IServiceInstanceProvider.hpp" +#include struct ServiceInstanceProviderMock : public sb::di::IServiceInstanceProvider { @@ -16,8 +16,8 @@ struct ServiceInstanceProviderMock : public sb::di::IServiceInstanceProvider MOCK_METHOD((sb::di::ServiceInstance), createInstance, (sb::di::TypeId serviceTypeId), (override)); MOCK_METHOD((sb::di::ServiceInstance), tryCreateInstanceInPlace, (sb::di::TypeId serviceTypeId), (override)); MOCK_METHOD((sb::di::ServiceInstance), createInstanceInPlace, (sb::di::TypeId serviceTypeId), (override)); - MOCK_METHOD((std::optional>), tryCreateInstances, - (sb::di::TypeId serviceTypeId), (override)); + MOCK_METHOD((sb::di::OneOrList), tryCreateInstances, (sb::di::TypeId serviceTypeId), + (override)); MOCK_METHOD((const sb::di::ServiceInstance *), tryGetKeyedInstance, (sb::di::TypeId serviceTypeId, std::string_view serviceKey), (override)); @@ -33,6 +33,6 @@ struct ServiceInstanceProviderMock : public sb::di::IServiceInstanceProvider (sb::di::TypeId serviceTypeId, std::string_view serviceKey), (override)); MOCK_METHOD((sb::di::ServiceInstance), createKeyedInstanceInPlace, (sb::di::TypeId serviceTypeId, std::string_view serviceKey), (override)); - MOCK_METHOD((std::optional>), tryCreateKeyedInstances, + MOCK_METHOD((sb::di::OneOrList), tryCreateKeyedInstances, (sb::di::TypeId serviceTypeId, std::string_view serviceKey), (override)); }; diff --git a/Tests/Helpers/Mocks/ServiceProviderMock.hpp b/Tests/Helpers/Mocks/ServiceProviderMock.hpp index 398873a..2414b5a 100644 --- a/Tests/Helpers/Mocks/ServiceProviderMock.hpp +++ b/Tests/Helpers/Mocks/ServiceProviderMock.hpp @@ -1,11 +1,11 @@ #pragma once #include "ServiceInstanceProviderMock.hpp" -#include "SevenBit/DI/ServiceProvider.hpp" +#include -struct ServiceProviderMock : public sb::di::ServiceProvider +struct ServiceProviderMock : sb::di::ServiceProvider { - ServiceProviderMock() : sb::di::ServiceProvider(prepare()) {} + ServiceProviderMock() : ServiceProvider(prepare()) {} [[nodiscard]] static sb::di::IServiceInstanceProvider::Ptr prepare() { diff --git a/Tests/Integration/AliasTest.cpp b/Tests/Integration/AliasTest.cpp index c11d43d..dca1adf 100644 --- a/Tests/Integration/AliasTest.cpp +++ b/Tests/Integration/AliasTest.cpp @@ -1,7 +1,7 @@ #include #include "../Helpers/Classes/MultiInherit.hpp" -#include "SevenBit/DI/ServiceCollection.hpp" +#include class AliasTest : public testing::Test { @@ -210,6 +210,43 @@ TEST_F(AliasTest, ShouldGetServices) EXPECT_TRUE(provider.getServices().empty()); } +TEST_F(AliasTest, ShouldGetMultipleServices) +{ + auto provider = sb::di::ServiceCollection{} + .addSingleton() + .addSingleton() + .addAlias() + .addAlias() + .addAlias() + .addAlias() + .buildServiceProvider(); + + const auto services = provider.getServices(); + + EXPECT_EQ(services.size(), 3); + EXPECT_EQ(services[0]->first(), 4); + EXPECT_EQ(services[1]->first(), 3); + EXPECT_EQ(services[2]->first(), 4); + EXPECT_EQ(services[2], services[0]); +} + +TEST_F(AliasTest, ShouldGetMultipleSomeWrongServices) +{ + auto provider = sb::di::ServiceCollection{} + .addSingleton() + .addAlias() + .addAlias() + .addAlias() + .addAlias() + .buildServiceProvider(); + + const auto services = provider.getServices(); + + EXPECT_EQ(services.size(), 2); + EXPECT_EQ(services[0]->first(), 4); + EXPECT_EQ(services[1]->first(), 4); +} + TEST_F(AliasTest, ShoulNotGetServices) { auto provider = sb::di::ServiceCollection{} @@ -242,6 +279,23 @@ TEST_F(AliasTest, ShouldGetCastedServicesInOrder) EXPECT_EQ(services[1]->first(), 4); } +TEST_F(AliasTest, ShouldGetCastedMultipleServicesInOrder) +{ + auto provider = sb::di::ServiceCollection{} + .addSingleton() + .addSingleton() + .addAlias() + .addAlias() + .addAlias() + .buildServiceProvider(); + + const auto services = provider.getServices(); + + EXPECT_EQ(services.size(), 2); + EXPECT_EQ(services[0]->first(), 4); + EXPECT_EQ(services[1]->first(), 3); +} + TEST_F(AliasTest, ShouldGetServicesInOrderAfterNormalGet) { auto provider = sb::di::ServiceCollection{} @@ -251,12 +305,52 @@ TEST_F(AliasTest, ShouldGetServicesInOrderAfterNormalGet) .buildServiceProvider(); EXPECT_TRUE(provider.tryGetService()); + const auto services = provider.getServices(); + EXPECT_EQ(services.size(), 2); EXPECT_EQ(services[0]->first(), 3); EXPECT_EQ(services[1]->first(), 4); } +TEST_F(AliasTest, ShouldGetMultipleServicesInOrderAfterNormalGet) +{ + auto provider = sb::di::ServiceCollection{} + .addSingleton() + .addSingleton() + .addAlias() + .addAlias() + .addAlias() + .buildServiceProvider(); + + EXPECT_TRUE(provider.tryGetService()); + + const auto services = provider.getServices(); + + EXPECT_EQ(services.size(), 2); + EXPECT_EQ(services[0]->first(), 4); + EXPECT_EQ(services[1]->first(), 3); +} + +TEST_F(AliasTest, ShouldGetNotMultipleServicesInOrderAfterNormalGet) +{ + auto provider = sb::di::ServiceCollection{} + .addSingleton() + .addSingleton() + .addAlias() + .addAlias() + .addAlias() + .buildServiceProvider(); + + EXPECT_FALSE(provider.tryGetService()); + + const auto services = provider.getServices(); + + EXPECT_EQ(services.size(), 2); + EXPECT_EQ(services[0]->first(), 4); + EXPECT_EQ(services[1]->first(), 3); +} + TEST_F(AliasTest, ShouldTryCreateService) { auto provider = sb::di::ServiceCollection{} @@ -369,6 +463,42 @@ TEST_F(AliasTest, ShouldCreateServices) EXPECT_TRUE(provider.createServices().empty()); } +TEST_F(AliasTest, ShouldCreateMultipleServices) +{ + auto provider = sb::di::ServiceCollection{} + .addTransient() + .addTransient() + .addAlias() + .addAlias() + .addAlias() + .addAlias() + .buildServiceProvider(); + + const auto services = provider.createServices(); + + EXPECT_EQ(services.size(), 3); + EXPECT_EQ(services[0]->first(), 4); + EXPECT_EQ(services[1]->first(), 3); + EXPECT_EQ(services[2]->first(), 4); +} + +TEST_F(AliasTest, ShouldCreateMultipleSomeWrongServices) +{ + auto provider = sb::di::ServiceCollection{} + .addTransient() + .addAlias() + .addAlias() + .addAlias() + .addAlias() + .buildServiceProvider(); + + const auto services = provider.createServices(); + + EXPECT_EQ(services.size(), 2); + EXPECT_EQ(services[0]->first(), 4); + EXPECT_EQ(services[1]->first(), 4); +} + TEST_F(AliasTest, ShoulNotCreateServices) { auto provider = sb::di::ServiceCollection{} diff --git a/Tests/Integration/BasicExternalTest.cpp b/Tests/Integration/BasicExternalTest.cpp index 8d215ab..0628d58 100644 --- a/Tests/Integration/BasicExternalTest.cpp +++ b/Tests/Integration/BasicExternalTest.cpp @@ -2,8 +2,8 @@ #include #include "../Helpers/Classes/Basic.hpp" -#include "SevenBit/DI/Exceptions.hpp" -#include "SevenBit/DI/ServiceCollection.hpp" +#include +#include class BasicExternalTest : public testing::Test { diff --git a/Tests/Integration/BasicFactoryTest.cpp b/Tests/Integration/BasicFactoryTest.cpp index 884232b..dc2da93 100644 --- a/Tests/Integration/BasicFactoryTest.cpp +++ b/Tests/Integration/BasicFactoryTest.cpp @@ -3,8 +3,8 @@ #include "../Helpers/Classes/Basic.hpp" #include "../Helpers/Classes/CirularDependency.hpp" -#include "SevenBit/DI/Exceptions.hpp" -#include "SevenBit/DI/ServiceCollection.hpp" +#include +#include class BasicFactoryTest : public testing::Test { diff --git a/Tests/Integration/BasicTest.cpp b/Tests/Integration/BasicTest.cpp index ed772c8..9b3752e 100644 --- a/Tests/Integration/BasicTest.cpp +++ b/Tests/Integration/BasicTest.cpp @@ -3,8 +3,8 @@ #include "../Helpers/Classes/Basic.hpp" #include "../Helpers/Classes/CirularDependency.hpp" -#include "SevenBit/DI/Exceptions.hpp" -#include "SevenBit/DI/ServiceCollection.hpp" +#include +#include class BasicTest : public testing::Test { diff --git a/Tests/Integration/BasicUniqFactoryTest.cpp b/Tests/Integration/BasicUniqFactoryTest.cpp index 8172678..33d27f4 100644 --- a/Tests/Integration/BasicUniqFactoryTest.cpp +++ b/Tests/Integration/BasicUniqFactoryTest.cpp @@ -4,8 +4,8 @@ #include "../Helpers/Classes/Basic.hpp" #include "../Helpers/Classes/CirularDependency.hpp" -#include "SevenBit/DI/Exceptions.hpp" -#include "SevenBit/DI/ServiceCollection.hpp" +#include +#include class BasicUniqFactoryTest : public testing::Test { diff --git a/Tests/Integration/InheritanceExternalTest.cpp b/Tests/Integration/InheritanceExternalTest.cpp index f9082d7..6d1bf63 100644 --- a/Tests/Integration/InheritanceExternalTest.cpp +++ b/Tests/Integration/InheritanceExternalTest.cpp @@ -2,8 +2,8 @@ #include #include "../Helpers/Classes/Inherit.hpp" -#include "SevenBit/DI/Exceptions.hpp" -#include "SevenBit/DI/ServiceCollection.hpp" +#include +#include class InheritanceExternalTest : public testing::Test { diff --git a/Tests/Integration/InheritanceFactoryTest.cpp b/Tests/Integration/InheritanceFactoryTest.cpp index 2cb920e..e0d5d36 100644 --- a/Tests/Integration/InheritanceFactoryTest.cpp +++ b/Tests/Integration/InheritanceFactoryTest.cpp @@ -2,8 +2,8 @@ #include #include "../Helpers/Classes/Inherit.hpp" -#include "SevenBit/DI/Exceptions.hpp" -#include "SevenBit/DI/ServiceCollection.hpp" +#include +#include class InheritanceFactoryTest : public testing::Test { diff --git a/Tests/Integration/InheritanceTest.cpp b/Tests/Integration/InheritanceTest.cpp index 225b493..fcee6f6 100644 --- a/Tests/Integration/InheritanceTest.cpp +++ b/Tests/Integration/InheritanceTest.cpp @@ -2,8 +2,8 @@ #include #include "../Helpers/Classes/Inherit.hpp" -#include "SevenBit/DI/Exceptions.hpp" -#include "SevenBit/DI/ServiceCollection.hpp" +#include +#include class InheritanceTest : public testing::Test { diff --git a/Tests/Integration/InheritanceUniqFactoryTest.cpp b/Tests/Integration/InheritanceUniqFactoryTest.cpp index 911b1da..5f1236e 100644 --- a/Tests/Integration/InheritanceUniqFactoryTest.cpp +++ b/Tests/Integration/InheritanceUniqFactoryTest.cpp @@ -2,8 +2,8 @@ #include #include "../Helpers/Classes/Inherit.hpp" -#include "SevenBit/DI/Exceptions.hpp" -#include "SevenBit/DI/ServiceCollection.hpp" +#include +#include class InheritanceUniqFactoryTest : public testing::Test { diff --git a/Tests/Integration/InjectionTest.cpp b/Tests/Integration/InjectionTest.cpp index d64a87a..d0362eb 100644 --- a/Tests/Integration/InjectionTest.cpp +++ b/Tests/Integration/InjectionTest.cpp @@ -2,7 +2,7 @@ #include #include "../Helpers/Classes/Complex.hpp" -#include "SevenBit/DI/ServiceCollection.hpp" +#include class InjectionTest : public testing::Test { diff --git a/Tests/Integration/Keyed/AliasKeyedTest.cpp b/Tests/Integration/Keyed/AliasKeyedTest.cpp index 4a30f68..b126932 100644 --- a/Tests/Integration/Keyed/AliasKeyedTest.cpp +++ b/Tests/Integration/Keyed/AliasKeyedTest.cpp @@ -1,7 +1,7 @@ #include #include "../../Helpers/Classes/MultiInherit.hpp" -#include "SevenBit/DI/ServiceCollection.hpp" +#include class AliasKeyedTest : public testing::Test { diff --git a/Tests/Integration/Keyed/BasicExternalKeyedTest.cpp b/Tests/Integration/Keyed/BasicExternalKeyedTest.cpp index d200dc3..d7373dd 100644 --- a/Tests/Integration/Keyed/BasicExternalKeyedTest.cpp +++ b/Tests/Integration/Keyed/BasicExternalKeyedTest.cpp @@ -2,8 +2,8 @@ #include #include "../../Helpers/Classes/Basic.hpp" -#include "SevenBit/DI/Exceptions.hpp" -#include "SevenBit/DI/ServiceCollection.hpp" +#include +#include class BasicExternalKeyedTest : public testing::Test { diff --git a/Tests/Integration/Keyed/BasicFactoryKeyedTest.cpp b/Tests/Integration/Keyed/BasicFactoryKeyedTest.cpp index a63d3db..6eeea59 100644 --- a/Tests/Integration/Keyed/BasicFactoryKeyedTest.cpp +++ b/Tests/Integration/Keyed/BasicFactoryKeyedTest.cpp @@ -2,8 +2,8 @@ #include #include "../../Helpers/Classes/Basic.hpp" -#include "SevenBit/DI/Exceptions.hpp" -#include "SevenBit/DI/ServiceCollection.hpp" +#include +#include class BasicFactoryKeyedTest : public testing::Test { diff --git a/Tests/Integration/Keyed/BasicKeyedTest.cpp b/Tests/Integration/Keyed/BasicKeyedTest.cpp index bb21728..d44b077 100644 --- a/Tests/Integration/Keyed/BasicKeyedTest.cpp +++ b/Tests/Integration/Keyed/BasicKeyedTest.cpp @@ -3,8 +3,8 @@ #include "../../Helpers/Classes/Basic.hpp" #include "../../Helpers/Classes/CirularDependency.hpp" -#include "SevenBit/DI/Exceptions.hpp" -#include "SevenBit/DI/ServiceCollection.hpp" +#include +#include class BasicKeyedTest : public testing::Test { diff --git a/Tests/Integration/Keyed/BasicUniqFactoryKeyedTest.cpp b/Tests/Integration/Keyed/BasicUniqFactoryKeyedTest.cpp index e1e9a5b..0040350 100644 --- a/Tests/Integration/Keyed/BasicUniqFactoryKeyedTest.cpp +++ b/Tests/Integration/Keyed/BasicUniqFactoryKeyedTest.cpp @@ -3,8 +3,8 @@ #include #include "../../Helpers/Classes/Basic.hpp" -#include "SevenBit/DI/Exceptions.hpp" -#include "SevenBit/DI/ServiceCollection.hpp" +#include +#include class BasicUniqFactoryKeyedTest : public testing::Test { diff --git a/Tests/Integration/Keyed/InheritanceExternalKeyedTest.cpp b/Tests/Integration/Keyed/InheritanceExternalKeyedTest.cpp index 48ffdc7..7cb2146 100644 --- a/Tests/Integration/Keyed/InheritanceExternalKeyedTest.cpp +++ b/Tests/Integration/Keyed/InheritanceExternalKeyedTest.cpp @@ -2,8 +2,8 @@ #include #include "../../Helpers/Classes/Inherit.hpp" -#include "SevenBit/DI/Exceptions.hpp" -#include "SevenBit/DI/ServiceCollection.hpp" +#include +#include class InheritanceExternalKeyedTest : public testing::Test { diff --git a/Tests/Integration/Keyed/InheritanceFactoryKeyedTest.cpp b/Tests/Integration/Keyed/InheritanceFactoryKeyedTest.cpp index 11d65b8..836b9b4 100644 --- a/Tests/Integration/Keyed/InheritanceFactoryKeyedTest.cpp +++ b/Tests/Integration/Keyed/InheritanceFactoryKeyedTest.cpp @@ -2,8 +2,8 @@ #include #include "../../Helpers/Classes/Inherit.hpp" -#include "SevenBit/DI/Exceptions.hpp" -#include "SevenBit/DI/ServiceCollection.hpp" +#include +#include class InheritanceFactoryKeyedTest : public testing::Test { diff --git a/Tests/Integration/Keyed/InheritanceKeyedTest.cpp b/Tests/Integration/Keyed/InheritanceKeyedTest.cpp index f497234..4e6d1b4 100644 --- a/Tests/Integration/Keyed/InheritanceKeyedTest.cpp +++ b/Tests/Integration/Keyed/InheritanceKeyedTest.cpp @@ -2,8 +2,8 @@ #include #include "../../Helpers/Classes/Inherit.hpp" -#include "SevenBit/DI/Exceptions.hpp" -#include "SevenBit/DI/ServiceCollection.hpp" +#include +#include class InheritanceKeyedTest : public testing::Test { diff --git a/Tests/Integration/Keyed/InheritanceUniqFactoryKeyedTest.cpp b/Tests/Integration/Keyed/InheritanceUniqFactoryKeyedTest.cpp index 1bb2d4e..dac2216 100644 --- a/Tests/Integration/Keyed/InheritanceUniqFactoryKeyedTest.cpp +++ b/Tests/Integration/Keyed/InheritanceUniqFactoryKeyedTest.cpp @@ -2,8 +2,8 @@ #include #include "../../Helpers/Classes/Inherit.hpp" -#include "SevenBit/DI/Exceptions.hpp" -#include "SevenBit/DI/ServiceCollection.hpp" +#include +#include class InheritanceUniqFactoryKeyedTest : public testing::Test { diff --git a/Tests/Integration/Keyed/MultiInheritanceExternalKeyedTest.cpp b/Tests/Integration/Keyed/MultiInheritanceExternalKeyedTest.cpp index be8119c..8ebd79a 100644 --- a/Tests/Integration/Keyed/MultiInheritanceExternalKeyedTest.cpp +++ b/Tests/Integration/Keyed/MultiInheritanceExternalKeyedTest.cpp @@ -2,7 +2,7 @@ #include #include "../../Helpers/Classes/MultiInherit.hpp" -#include "SevenBit/DI/ServiceCollection.hpp" +#include class MultiInheritanceExternalKeyedTest : public testing::Test { diff --git a/Tests/Integration/Keyed/MultiInheritanceFactoryKeyedTest.cpp b/Tests/Integration/Keyed/MultiInheritanceFactoryKeyedTest.cpp index e35590a..d8d40b5 100644 --- a/Tests/Integration/Keyed/MultiInheritanceFactoryKeyedTest.cpp +++ b/Tests/Integration/Keyed/MultiInheritanceFactoryKeyedTest.cpp @@ -2,7 +2,7 @@ #include #include "../../Helpers/Classes/MultiInherit.hpp" -#include "SevenBit/DI/ServiceCollection.hpp" +#include class MultiInheritanceFactoryKeyedTest : public testing::Test { diff --git a/Tests/Integration/Keyed/MultiInheritanceKeyedTest.cpp b/Tests/Integration/Keyed/MultiInheritanceKeyedTest.cpp index e2b62f0..9082537 100644 --- a/Tests/Integration/Keyed/MultiInheritanceKeyedTest.cpp +++ b/Tests/Integration/Keyed/MultiInheritanceKeyedTest.cpp @@ -2,7 +2,7 @@ #include #include "../../Helpers/Classes/MultiInherit.hpp" -#include "SevenBit/DI/ServiceCollection.hpp" +#include class MultiInheritanceKeyedTest : public testing::Test { diff --git a/Tests/Integration/Keyed/MultiInheritanceUniqFactoryKeyedTest.cpp b/Tests/Integration/Keyed/MultiInheritanceUniqFactoryKeyedTest.cpp index f6a8bdd..6f50abb 100644 --- a/Tests/Integration/Keyed/MultiInheritanceUniqFactoryKeyedTest.cpp +++ b/Tests/Integration/Keyed/MultiInheritanceUniqFactoryKeyedTest.cpp @@ -2,7 +2,7 @@ #include #include "../../Helpers/Classes/MultiInherit.hpp" -#include "SevenBit/DI/ServiceCollection.hpp" +#include class MultiInheritanceUniqFactoryKeyedTest : public testing::Test { diff --git a/Tests/Integration/MultiInheritanceExternalTest.cpp b/Tests/Integration/MultiInheritanceExternalTest.cpp index 3de2861..9e0753f 100644 --- a/Tests/Integration/MultiInheritanceExternalTest.cpp +++ b/Tests/Integration/MultiInheritanceExternalTest.cpp @@ -2,7 +2,7 @@ #include #include "../Helpers/Classes/MultiInherit.hpp" -#include "SevenBit/DI/ServiceCollection.hpp" +#include class MultiInheritanceExternalTest : public testing::Test { diff --git a/Tests/Integration/MultiInheritanceFactoryTest.cpp b/Tests/Integration/MultiInheritanceFactoryTest.cpp index 91d7a2f..eea7107 100644 --- a/Tests/Integration/MultiInheritanceFactoryTest.cpp +++ b/Tests/Integration/MultiInheritanceFactoryTest.cpp @@ -2,7 +2,7 @@ #include #include "../Helpers/Classes/MultiInherit.hpp" -#include "SevenBit/DI/ServiceCollection.hpp" +#include class MultiInheritanceFactoryTest : public testing::Test { diff --git a/Tests/Integration/MultiInheritanceTest.cpp b/Tests/Integration/MultiInheritanceTest.cpp index fa50bb7..6e9bd09 100644 --- a/Tests/Integration/MultiInheritanceTest.cpp +++ b/Tests/Integration/MultiInheritanceTest.cpp @@ -2,7 +2,7 @@ #include #include "../Helpers/Classes/MultiInherit.hpp" -#include "SevenBit/DI/ServiceCollection.hpp" +#include class MultiInheritanceTest : public testing::Test { diff --git a/Tests/Integration/MultiInheritanceUniqFactoryTest.cpp b/Tests/Integration/MultiInheritanceUniqFactoryTest.cpp index c4dff2e..a1115c4 100644 --- a/Tests/Integration/MultiInheritanceUniqFactoryTest.cpp +++ b/Tests/Integration/MultiInheritanceUniqFactoryTest.cpp @@ -2,7 +2,7 @@ #include #include "../Helpers/Classes/MultiInherit.hpp" -#include "SevenBit/DI/ServiceCollection.hpp" +#include class MultiInheritanceUniqFactoryTest : public testing::Test { diff --git a/Tests/Integration/ScopeTest.cpp b/Tests/Integration/ScopeTest.cpp index 217e330..17b4c9b 100644 --- a/Tests/Integration/ScopeTest.cpp +++ b/Tests/Integration/ScopeTest.cpp @@ -4,7 +4,7 @@ #include "../Helpers/Classes/Basic.hpp" #include "../Helpers/Classes/Complex.hpp" #include "../Helpers/Classes/Dependencies.hpp" -#include "SevenBit/DI/ServiceCollection.hpp" +#include class ScopeTest : public testing::Test { diff --git a/Tests/Unit/Containers/ServiceDescriptorListTest.cpp b/Tests/Unit/Containers/ServiceDescriptorListTest.cpp index 84c5baf..8c84c0c 100644 --- a/Tests/Unit/Containers/ServiceDescriptorListTest.cpp +++ b/Tests/Unit/Containers/ServiceDescriptorListTest.cpp @@ -1,9 +1,9 @@ #include #include "../../Helpers/Classes/Inherit.hpp" -#include "SevenBit/DI/Details/Containers/ServiceDescriptorList.hpp" -#include "SevenBit/DI/Exceptions.hpp" -#include "SevenBit/DI/ServiceDescriber.hpp" +#include +#include +#include class ServiceDescriptorListTest : public testing::Test { diff --git a/Tests/Unit/Containers/ServiceDescriptorsMapTest.cpp b/Tests/Unit/Containers/ServiceDescriptorsMapTest.cpp index 74e424a..7f2e570 100644 --- a/Tests/Unit/Containers/ServiceDescriptorsMapTest.cpp +++ b/Tests/Unit/Containers/ServiceDescriptorsMapTest.cpp @@ -1,8 +1,8 @@ #include #include "../../Helpers/Classes/Inherit.hpp" -#include "SevenBit/DI/Details/Containers/ServiceDescriptorsMap.hpp" -#include "SevenBit/DI/ServiceDescriber.hpp" +#include +#include class ServiceDescriptorsMapTest : public testing::Test { diff --git a/Tests/Unit/Containers/ServiceInstanceListTest.cpp b/Tests/Unit/Containers/ServiceInstanceListTest.cpp index cdb1ff0..a97d180 100644 --- a/Tests/Unit/Containers/ServiceInstanceListTest.cpp +++ b/Tests/Unit/Containers/ServiceInstanceListTest.cpp @@ -2,11 +2,11 @@ #include #include "../../Helpers/Classes/Basic.hpp" -#include "SevenBit/DI/Details/Containers/ServiceInstanceList.hpp" -#include "SevenBit/DI/Details/Services/ExternalService.hpp" -#include "SevenBit/DI/Details/Services/InPlaceService.hpp" -#include "SevenBit/DI/Details/Services/UniquePtrService.hpp" -#include "SevenBit/DI/Exceptions.hpp" +#include +#include +#include +#include +#include class ServiceInstanceListTest : public testing::Test { @@ -34,24 +34,6 @@ TEST_F(ServiceInstanceListTest, ShouldAddServices) list.add(sb::di::ServiceInstance{std::move(implementation2)}); } -TEST_F(ServiceInstanceListTest, ShouldFailAddNullService) -{ - auto act = [&] { sb::di::details::ServiceInstanceList list{sb::di::ServiceInstance{}}; }; - - EXPECT_THROW(act(), sb::di::InvalidServiceException); -} - -TEST_F(ServiceInstanceListTest, ShouldFailAddInvalidService) -{ - auto act = [&] { - auto implementation = - std::make_unique>(std::unique_ptr{}); - sb::di::details::ServiceInstanceList list{sb::di::ServiceInstance{std::move(implementation)}}; - }; - - EXPECT_THROW(act(), sb::di::InvalidServiceException); -} - TEST_F(ServiceInstanceListTest, ShouldReturnProperSize) { auto implementation = std::make_unique>(); diff --git a/Tests/Unit/Containers/ServiceInstancesMapTest.cpp b/Tests/Unit/Containers/ServiceInstancesMapTest.cpp index dfb2bdd..ebf0331 100644 --- a/Tests/Unit/Containers/ServiceInstancesMapTest.cpp +++ b/Tests/Unit/Containers/ServiceInstancesMapTest.cpp @@ -5,9 +5,9 @@ #include "../../Helpers/Classes/Inherit.hpp" #include "../../Helpers/Classes/InheritDesctuction.hpp" #include "../../Helpers/Mocks/ServiceProviderMock.hpp" -#include "SevenBit/DI/Details/Containers/ServiceInstancesMap.hpp" -#include "SevenBit/DI/Details/Services/ExternalService.hpp" -#include "SevenBit/DI/ServiceDescriber.hpp" +#include +#include +#include class ServiceInstancesMapTest : public testing::Test { diff --git a/Tests/Unit/Core/ServiceAliasesCreatorTest.cpp b/Tests/Unit/Core/ServiceAliasesCreatorTest.cpp new file mode 100644 index 0000000..92a43c0 --- /dev/null +++ b/Tests/Unit/Core/ServiceAliasesCreatorTest.cpp @@ -0,0 +1,206 @@ +#include +#include + +#include "../../Helpers/Classes/Inherit.hpp" +#include "../../Helpers/Mocks/ServiceProviderMock.hpp" +#include +#include + +class ServiceAliasesCreatorTest : public testing::Test +{ + protected: + static void SetUpTestSuite() {} + + ServiceAliasesCreatorTest() {} + + void SetUp() override {} + + void TearDown() override {} + + ~ServiceAliasesCreatorTest() override = default; + + static void TearDownTestSuite() {} +}; + +TEST_F(ServiceAliasesCreatorTest, ShouldFailCreateAliasForInvalidService) +{ + constexpr sb::di::details::ServiceAliasesCreator creator; + + const auto descriptor = sb::di::ServiceDescriber::describeAlias(); + + const sb::di::ServiceInstance external; + + EXPECT_THROW(creator.tryCreate(descriptor, &external), sb::di::InvalidServiceException); +} + +TEST_F(ServiceAliasesCreatorTest, ShouldFailCreateAliasForNullService) +{ + constexpr sb::di::details::ServiceAliasesCreator creator; + + const auto descriptor = sb::di::ServiceDescriber::describeAlias(); + + TestInheritClass5 *test = nullptr; + const sb::di::ServiceInstance external{std::make_unique>(test)}; + + EXPECT_THROW(creator.tryCreate(descriptor, &external), sb::di::InvalidServiceException); +} + +TEST_F(ServiceAliasesCreatorTest, ShouldFailCreateAliasForWrongDescriptor) +{ + constexpr sb::di::details::ServiceAliasesCreator creator; + + const auto descriptor = sb::di::ServiceDescriber::describeSingleton(); + + TestInheritClass5 *test = nullptr; + const sb::di::ServiceInstance external{std::make_unique>(test)}; + + EXPECT_THROW(creator.tryCreate(descriptor, &external), sb::di::InjectorException); +} + +TEST_F(ServiceAliasesCreatorTest, ShouldCreate) +{ + constexpr sb::di::details::ServiceAliasesCreator creator; + + TestInheritClass6 test; + const sb::di::ServiceInstance external{ + std::make_unique>(&test)}; + + const auto instance = + creator.tryCreate(sb::di::ServiceDescriber::describeAlias(), &external); + + EXPECT_TRUE(instance); + EXPECT_TRUE(instance.isValid()); + EXPECT_TRUE(instance.getAs()); + EXPECT_EQ(instance.tryGetImplementation()->getTypeId(), typeid(TestInheritClass5)); +} + +TEST_F(ServiceAliasesCreatorTest, ShouldNotCreateForNullOriginal) +{ + constexpr sb::di::details::ServiceAliasesCreator creator; + + TestInheritClass6 test; + const sb::di::ServiceInstance external{ + std::make_unique>(&test)}; + + const auto instance = + creator.tryCreate(sb::di::ServiceDescriber::describeAlias(), nullptr); + + EXPECT_FALSE(instance); + EXPECT_FALSE(instance.isValid()); +} + +TEST_F(ServiceAliasesCreatorTest, ShouldCreateAllAliases) +{ + sb::di::details::ServiceDescriptorList descriptors{ + sb::di::ServiceDescriber::describeAlias()}; + + constexpr sb::di::details::ServiceAliasesCreator creator; + + TestInheritClass3 test3; + TestInheritClass4 test4; + TestInheritClass5 test5; + sb::di::details::ServiceInstanceList externals{ + sb::di::ServiceInstance{std::make_unique>(&test3)}}; + externals.add( + sb::di::ServiceInstance{std::make_unique>(&test4)}); + externals.add( + sb::di::ServiceInstance{std::make_unique>(&test5)}); + + const auto instances = + creator.tryCreateAll(descriptors, [&](const sb::di::ServiceDescriptor &) { return &externals; }); + + EXPECT_EQ(instances.size(), 3); + EXPECT_FALSE(instances.isSealed()); + EXPECT_TRUE(instances[0].isValid()); + EXPECT_TRUE(instances[0].getAs()); + EXPECT_EQ(instances[0].tryGetImplementation()->getTypeId(), typeid(TestInheritClass2)); + EXPECT_TRUE(instances[1].isValid()); + EXPECT_TRUE(instances[1].getAs()); + EXPECT_EQ(instances[1].tryGetImplementation()->getTypeId(), typeid(TestInheritClass2)); + EXPECT_TRUE(instances[2].isValid()); + EXPECT_TRUE(instances[2].getAs()); + EXPECT_EQ(instances[2].tryGetImplementation()->getTypeId(), typeid(TestInheritClass2)); +} + +TEST_F(ServiceAliasesCreatorTest, ShouldNotCreateAllAliasesForEmpty) +{ + sb::di::details::ServiceDescriptorList descriptors; + + constexpr sb::di::details::ServiceAliasesCreator creator; + + sb::di::details::ServiceInstanceList externals; + + const auto instances = + creator.tryCreateAll(descriptors, [&](const sb::di::ServiceDescriptor &) { return &externals; }); + + EXPECT_FALSE(instances); + EXPECT_TRUE(instances.empty()); +} + +TEST_F(ServiceAliasesCreatorTest, ShouldNotCreateAllAliasesForNull) +{ + const sb::di::details::ServiceDescriptorList descriptors{ + sb::di::ServiceDescriber::describeAlias()}; + + constexpr sb::di::details::ServiceAliasesCreator creator; + const auto instances = creator.tryCreateAll( + descriptors, + [&](const sb::di::ServiceDescriptor &) -> sb::di::details::ServiceInstanceList * { return nullptr; }); + + EXPECT_FALSE(instances); + EXPECT_TRUE(instances.empty()); +} + +TEST_F(ServiceAliasesCreatorTest, ShouldCreateSkippedAliases) +{ + sb::di::details::ServiceDescriptorList descriptors{ + sb::di::ServiceDescriber::describeAlias()}; + + constexpr sb::di::details::ServiceAliasesCreator creator; + + TestInheritClass3 test3; + TestInheritClass4 test4; + TestInheritClass5 test5; + sb::di::details::ServiceInstanceList externals{ + sb::di::ServiceInstance{std::make_unique>(&test3)}}; + externals.add( + sb::di::ServiceInstance{std::make_unique>(&test4)}); + externals.add( + sb::di::ServiceInstance{std::make_unique>(&test5)}); + + const auto instances = + creator.tryCreateAll(descriptors, [&](const sb::di::ServiceDescriptor &) { return &externals; }, 1); + + EXPECT_EQ(instances.size(), 2); + EXPECT_FALSE(instances.isSealed()); + EXPECT_TRUE(instances[0].isValid()); + EXPECT_TRUE(instances[0].getAs()); + EXPECT_EQ(instances[0].tryGetImplementation()->getTypeId(), typeid(TestInheritClass2)); + EXPECT_TRUE(instances[1].isValid()); + EXPECT_TRUE(instances[1].getAs()); + EXPECT_EQ(instances[1].tryGetImplementation()->getTypeId(), typeid(TestInheritClass2)); +} + +TEST_F(ServiceAliasesCreatorTest, ShouldNotCreateSkippedAliases) +{ + const sb::di::details::ServiceDescriptorList descriptors{ + sb::di::ServiceDescriber::describeAlias()}; + + constexpr sb::di::details::ServiceAliasesCreator creator; + + TestInheritClass3 test3; + TestInheritClass4 test4; + TestInheritClass5 test5; + sb::di::details::ServiceInstanceList externals{ + sb::di::ServiceInstance{std::make_unique>(&test3)}}; + externals.add( + sb::di::ServiceInstance{std::make_unique>(&test4)}); + externals.add( + sb::di::ServiceInstance{std::make_unique>(&test5)}); + + const auto instances = + creator.tryCreateAll(descriptors, [&](const sb::di::ServiceDescriptor &) { return &externals; }, 5); + + EXPECT_TRUE(instances.empty()); + EXPECT_FALSE(instances.isSealed()); +} diff --git a/Tests/Unit/Core/ServiceInstanceCreatorTest.cpp b/Tests/Unit/Core/ServiceInstanceCreatorTest.cpp deleted file mode 100644 index 57104c7..0000000 --- a/Tests/Unit/Core/ServiceInstanceCreatorTest.cpp +++ /dev/null @@ -1,139 +0,0 @@ -#include -#include - -#include "../../Helpers/Classes/Basic.hpp" -#include "../../Helpers/Classes/CirularDependency.hpp" -#include "../../Helpers/Classes/Inherit.hpp" -#include "../../Helpers/Mocks/ServiceProviderMock.hpp" -#include "SevenBit/DI/Details/Core/ServiceInstanceCreator.hpp" -#include "SevenBit/DI/Exceptions.hpp" -#include "SevenBit/DI/ServiceDescriber.hpp" - -class ServiceInstanceCreatorTest : public testing::Test -{ - protected: - static void SetUpTestSuite() {} - - ServiceInstanceCreatorTest() {} - - void SetUp() override {} - - void TearDown() override {} - - ~ServiceInstanceCreatorTest() override = default; - - static void TearDownTestSuite() {} -}; - -TEST_F(ServiceInstanceCreatorTest, ShouldCreateInstance) -{ - ServiceProviderMock mock; - sb::di::details::ServiceInstanceCreator creator; - creator.setServiceProvider(mock); - - const auto descriptor = sb::di::ServiceDescriber::describeSingleton(); - - const auto instance = creator.createInstance(descriptor, false); - - EXPECT_TRUE(instance); - EXPECT_TRUE(instance.isValid()); - EXPECT_TRUE(instance.getAs()); - EXPECT_EQ(instance.tryGetImplementation()->getTypeId(), typeid(TestClass1)); -} - -TEST_F(ServiceInstanceCreatorTest, ShouldCreateInstanceAlias) -{ - sb::di::details::ServiceInstanceCreator creator; - - const auto descriptor = sb::di::ServiceDescriber::describeAlias(); - - TestInheritClass5 test; - const sb::di::ServiceInstance external{ - std::make_unique>(&test)}; - const auto instance = creator.createInstanceAlias(descriptor, external); - - EXPECT_TRUE(instance.isValid()); - EXPECT_TRUE(instance.getAs()); - EXPECT_EQ(instance.tryGetImplementation()->getTypeId(), typeid(TestInheritClass5)); -} - -TEST_F(ServiceInstanceCreatorTest, ShouldFailForNullProvider) -{ - ServiceProviderMock mock; - sb::di::details::ServiceInstanceCreator creator; - - const auto descriptor = sb::di::ServiceDescriber::describeSingleton(); - - EXPECT_THROW(creator.createInstance(descriptor, false), sb::di::NullPointerException); -} - -TEST_F(ServiceInstanceCreatorTest, ShouldFailForInvalidInstance) -{ - ServiceProviderMock mock; - sb::di::details::ServiceInstanceCreator creator; - creator.setServiceProvider(mock); - - const auto descriptor = sb::di::ServiceDescriber::describeSingleton(nullptr); - - EXPECT_THROW(creator.createInstance(descriptor, false), sb::di::InvalidServiceException); -} - -TEST_F(ServiceInstanceCreatorTest, ShouldFailFoWringDescriptor) -{ - ServiceProviderMock mock; - sb::di::details::ServiceInstanceCreator creator; - creator.setServiceProvider(mock); - - const auto descriptor = sb::di::ServiceDescriber::describeAlias(); - - EXPECT_THROW(creator.createInstance(descriptor, false), sb::di::InjectorException); -} - -TEST_F(ServiceInstanceCreatorTest, ShouldFailForCirculatDependency) -{ - ServiceProviderMock mock; - sb::di::details::ServiceInstanceCreator creator; - creator.setServiceProvider(mock); - - EXPECT_CALL(mock.getMock(), tryGetInstance(sb::di::TypeId{typeid(CircularDependencyA)})) - .WillOnce(testing::Invoke([&](sb::di::TypeId typeId) { - const auto descriptor = sb::di::ServiceDescriber::describeSingleton(); - creator.createInstance(descriptor, false); - return nullptr; - })); - - EXPECT_CALL(mock.getMock(), tryGetInstance(sb::di::TypeId{typeid(CircularDependencyB)})) - .WillOnce(testing::Invoke([&](sb::di::TypeId typeId) { - const auto descriptor = sb::di::ServiceDescriber::describeSingleton(); - creator.createInstance(descriptor, false); - return nullptr; - })); - - const auto descriptor = sb::di::ServiceDescriber::describeSingleton(); - - EXPECT_THROW(creator.createInstance(descriptor, false), sb::di::CircularDependencyException); -} - -TEST_F(ServiceInstanceCreatorTest, ShouldFailCreateInstanceAliasForNullService) -{ - sb::di::details::ServiceInstanceCreator creator; - - const auto descriptor = sb::di::ServiceDescriber::describeAlias(); - - TestInheritClass5 *test = nullptr; - const sb::di::ServiceInstance external{std::make_unique>(test)}; - - EXPECT_THROW(creator.createInstanceAlias(descriptor, external), sb::di::InvalidServiceException); -} - -TEST_F(ServiceInstanceCreatorTest, ShouldFailCreateInstanceAliasForWrongDescriptor) -{ - sb::di::details::ServiceInstanceCreator creator; - - const auto descriptor = sb::di::ServiceDescriber::describeSingleton(); - - TestInheritClass5 *test = nullptr; - const sb::di::ServiceInstance external{std::make_unique>(test)}; - - EXPECT_THROW(creator.createInstanceAlias(descriptor, external), sb::di::InjectorException); -} diff --git a/Tests/Unit/Core/ServiceInstanceProviderRootTest.cpp b/Tests/Unit/Core/ServiceInstanceProviderRootTest.cpp index b737061..e90cd2f 100644 --- a/Tests/Unit/Core/ServiceInstanceProviderRootTest.cpp +++ b/Tests/Unit/Core/ServiceInstanceProviderRootTest.cpp @@ -4,9 +4,9 @@ #include "../../Helpers/Classes/Basic.hpp" #include "../../Helpers/Classes/Inherit.hpp" #include "../../Helpers/Mocks/ServiceProviderMock.hpp" -#include "SevenBit/DI/Details/Core/ServiceInstanceProviderRoot.hpp" -#include "SevenBit/DI/Exceptions.hpp" -#include "SevenBit/DI/ServiceDescriber.hpp" +#include +#include +#include class ServiceInstanceProviderRootTest : public testing::Test { @@ -917,7 +917,7 @@ TEST_F(ServiceInstanceProviderRootTest, ShouldCreateInstances) EXPECT_FALSE(provider.tryCreateInstances(typeid(TestClass1))); EXPECT_FALSE(provider.tryCreateInstances(typeid(TestClass2))); - EXPECT_EQ(provider.tryCreateInstances(typeid(TestClass3))->size(), 1); + EXPECT_EQ(provider.tryCreateInstances(typeid(TestClass3)).size(), 1); EXPECT_FALSE(provider.tryCreateInstances(typeid(TestClass4))); EXPECT_FALSE(provider.tryCreateInstances(typeid(TestInheritClass5))); EXPECT_FALSE(provider.tryCreateInstances(typeid(TestInheritClass6))); @@ -941,7 +941,7 @@ TEST_F(ServiceInstanceProviderRootTest, ShouldCreateKeyedInstances) EXPECT_FALSE(provider.tryCreateKeyedInstances(typeid(TestClass1), "key")); EXPECT_FALSE(provider.tryCreateKeyedInstances(typeid(TestClass2), "key")); - EXPECT_EQ(provider.tryCreateKeyedInstances(typeid(TestClass3), "key")->size(), 1); + EXPECT_EQ(provider.tryCreateKeyedInstances(typeid(TestClass3), "key").size(), 1); EXPECT_FALSE(provider.tryCreateKeyedInstances(typeid(TestClass4), "key")); EXPECT_FALSE(provider.tryCreateKeyedInstances(typeid(TestInheritClass5), "key")); EXPECT_FALSE(provider.tryCreateKeyedInstances(typeid(TestInheritClass6), "key")); @@ -962,7 +962,7 @@ TEST_F(ServiceInstanceProviderRootTest, ShouldCreateInstancesInOrder) sb::di::details::ServiceInstanceProviderRoot provider(describers.begin(), describers.end()); provider.init(mock); - auto services = *provider.tryCreateInstances(typeid(TestInheritClass1)); + auto services = provider.tryCreateInstances(typeid(TestInheritClass1)); EXPECT_EQ(services.size(), 5); EXPECT_EQ(static_cast(services[0].getAs())->number(), 1); EXPECT_EQ(static_cast(services[1].getAs())->number(), 2); @@ -994,7 +994,7 @@ TEST_F(ServiceInstanceProviderRootTest, ShouldCreateKeyedInstancesInOrder) sb::di::details::ServiceInstanceProviderRoot provider(describers.begin(), describers.end()); provider.init(mock); - auto services = *provider.tryCreateKeyedInstances(typeid(TestInheritClass1), "key"); + auto services = provider.tryCreateKeyedInstances(typeid(TestInheritClass1), "key"); EXPECT_EQ(services.size(), 5); EXPECT_EQ(static_cast(services[0].getAs())->number(), 1); EXPECT_EQ(static_cast(services[1].getAs())->number(), 2); @@ -1021,7 +1021,7 @@ TEST_F(ServiceInstanceProviderRootTest, ShouldCreateAliasInstancesInOrder) sb::di::details::ServiceInstanceProviderRoot provider(describers.begin(), describers.end()); provider.init(mock); - auto services = *provider.tryCreateInstances(typeid(TestInheritClass1)); + auto services = provider.tryCreateInstances(typeid(TestInheritClass1)); EXPECT_EQ(services.size(), 5); EXPECT_EQ(static_cast(services[0].getAs())->number(), 2); EXPECT_EQ(static_cast(services[1].getAs())->number(), 3); @@ -1051,7 +1051,7 @@ TEST_F(ServiceInstanceProviderRootTest, ShouldCreateKeyedAliasInstancesInOrder) sb::di::details::ServiceInstanceProviderRoot provider(describers.begin(), describers.end()); provider.init(mock); - auto services = *provider.tryCreateKeyedInstances(typeid(TestInheritClass1), "key"); + auto services = provider.tryCreateKeyedInstances(typeid(TestInheritClass1), "key"); EXPECT_EQ(services.size(), 5); EXPECT_EQ(static_cast(services[0].getAs())->number(), 2); EXPECT_EQ(static_cast(services[1].getAs())->number(), 3); diff --git a/Tests/Unit/Core/ServiceInstanceResolverTest.cpp b/Tests/Unit/Core/ServiceInstanceResolverTest.cpp deleted file mode 100644 index e6296a2..0000000 --- a/Tests/Unit/Core/ServiceInstanceResolverTest.cpp +++ /dev/null @@ -1,445 +0,0 @@ -#include -#include - -#include "../../Helpers/Classes/Basic.hpp" -#include "../../Helpers/Classes/Inherit.hpp" -#include "../../Helpers/Mocks/ServiceProviderMock.hpp" -#include "SevenBit/DI/Details/Core/ServiceInstancesResolver.hpp" -#include "SevenBit/DI/ServiceDescriber.hpp" - -class ServiceInstanceResolverTest : public testing::Test -{ - protected: - static void SetUpTestSuite() {} - - ServiceInstanceResolverTest() {} - - void SetUp() override {} - - void TearDown() override {} - - ~ServiceInstanceResolverTest() override = default; - - static void TearDownTestSuite() {} -}; - -TEST_F(ServiceInstanceResolverTest, ShouldCreateInstance) -{ - ServiceProviderMock mock; - sb::di::details::ServiceInstanceCreator creator; - creator.setServiceProvider(mock); - const sb::di::details::ServiceDescriptorList descriptors{sb::di::ServiceDescriber::describeSingleton()}; - - const sb::di::details::ServiceInstancesResolver resolver{creator, descriptors}; - - const auto instance = resolver.createInstance(); - - EXPECT_TRUE(instance); - EXPECT_TRUE(instance.isValid()); - EXPECT_TRUE(instance.getAs()); - EXPECT_EQ(instance.tryGetImplementation()->getTypeId(), typeid(TestClass1)); -} - -TEST_F(ServiceInstanceResolverTest, ShouldCreateInheritedInstance) -{ - ServiceProviderMock mock; - sb::di::details::ServiceInstanceCreator creator; - creator.setServiceProvider(mock); - sb::di::details::ServiceDescriptorList descriptors{ - sb::di::ServiceDescriber::describeSingleton()}; - descriptors.add(sb::di::ServiceDescriber::describeSingleton()); - descriptors.add(sb::di::ServiceDescriber::describeSingleton()); - - const sb::di::details::ServiceInstancesResolver resolver{creator, descriptors}; - - const auto instance = resolver.createInstance(); - - EXPECT_TRUE(instance); - EXPECT_TRUE(instance.isValid()); - EXPECT_TRUE(instance.getAs()); - EXPECT_EQ(instance.tryGetImplementation()->getTypeId(), typeid(TestInheritClass4)); -} - -TEST_F(ServiceInstanceResolverTest, ShouldCreateOneInstance) -{ - ServiceProviderMock mock; - sb::di::details::ServiceInstanceCreator creator; - creator.setServiceProvider(mock); - const sb::di::details::ServiceDescriptorList descriptors{sb::di::ServiceDescriber::describeSingleton()}; - - const sb::di::details::ServiceInstancesResolver resolver{creator, descriptors}; - - const auto instances = resolver.createOneInstance(); - - EXPECT_EQ(instances.size(), 1); - EXPECT_TRUE(instances.isSealed()); - EXPECT_TRUE(instances.getInnerList()[0].isValid()); - EXPECT_TRUE(instances.getInnerList()[0].getAs()); - EXPECT_EQ(instances.getInnerList()[0].tryGetImplementation()->getTypeId(), typeid(TestClass1)); -} - -TEST_F(ServiceInstanceResolverTest, ShouldCreateOneInheritedInstance) -{ - ServiceProviderMock mock; - sb::di::details::ServiceInstanceCreator creator; - creator.setServiceProvider(mock); - sb::di::details::ServiceDescriptorList descriptors{ - sb::di::ServiceDescriber::describeSingleton()}; - descriptors.add(sb::di::ServiceDescriber::describeSingleton()); - descriptors.add(sb::di::ServiceDescriber::describeSingleton()); - - const sb::di::details::ServiceInstancesResolver resolver{creator, descriptors}; - - const auto instances = resolver.createOneInstance(); - - EXPECT_EQ(instances.size(), 1); - EXPECT_FALSE(instances.isSealed()); - EXPECT_TRUE(instances.getInnerList()[0].isValid()); - EXPECT_TRUE(instances.getInnerList()[0].getAs()); - EXPECT_EQ(instances.getInnerList()[0].tryGetImplementation()->getTypeId(), typeid(TestInheritClass4)); -} - -TEST_F(ServiceInstanceResolverTest, ShouldCreateAllInstances) -{ - ServiceProviderMock mock; - sb::di::details::ServiceInstanceCreator creator; - creator.setServiceProvider(mock); - const sb::di::details::ServiceDescriptorList descriptors{sb::di::ServiceDescriber::describeSingleton()}; - - const sb::di::details::ServiceInstancesResolver resolver{creator, descriptors}; - - const auto instances = resolver.createAllInstances(); - - EXPECT_EQ(instances.size(), 1); - EXPECT_TRUE(instances.isSealed()); - EXPECT_TRUE(instances.getInnerList()[0].isValid()); - EXPECT_TRUE(instances.getInnerList()[0].getAs()); - EXPECT_EQ(instances.getInnerList()[0].tryGetImplementation()->getTypeId(), typeid(TestClass1)); -} - -TEST_F(ServiceInstanceResolverTest, ShouldCreateAllInheritedInstances) -{ - ServiceProviderMock mock; - sb::di::details::ServiceInstanceCreator creator; - creator.setServiceProvider(mock); - sb::di::details::ServiceDescriptorList descriptors{ - sb::di::ServiceDescriber::describeSingleton()}; - descriptors.add(sb::di::ServiceDescriber::describeSingleton()); - descriptors.add(sb::di::ServiceDescriber::describeSingleton()); - - const sb::di::details::ServiceInstancesResolver resolver{creator, descriptors}; - - const auto instances = resolver.createAllInstances(); - - EXPECT_EQ(instances.size(), 3); - EXPECT_TRUE(instances.isSealed()); - EXPECT_TRUE(instances.getInnerList()[0].isValid()); - EXPECT_TRUE(instances.getInnerList()[0].getAs()); - EXPECT_EQ(instances.getInnerList()[0].tryGetImplementation()->getTypeId(), typeid(TestInheritClass3)); - EXPECT_TRUE(instances.getInnerList()[1].isValid()); - EXPECT_TRUE(instances.getInnerList()[1].getAs()); - EXPECT_EQ(instances.getInnerList()[1].tryGetImplementation()->getTypeId(), typeid(TestInheritClass5)); - EXPECT_TRUE(instances.getInnerList()[2].isValid()); - EXPECT_TRUE(instances.getInnerList()[2].getAs()); - EXPECT_EQ(instances.getInnerList()[2].tryGetImplementation()->getTypeId(), typeid(TestInheritClass4)); -} - -TEST_F(ServiceInstanceResolverTest, ShouldCreateRestInheritedInstances) -{ - ServiceProviderMock mock; - sb::di::details::ServiceInstanceCreator creator; - creator.setServiceProvider(mock); - sb::di::details::ServiceDescriptorList descriptors{ - sb::di::ServiceDescriber::describeSingleton()}; - descriptors.add(sb::di::ServiceDescriber::describeSingleton()); - descriptors.add(sb::di::ServiceDescriber::describeSingleton()); - - const sb::di::details::ServiceInstancesResolver resolver{creator, descriptors}; - - sb::di::details::ServiceInstanceList instances{ - sb::di::ServiceInstance{descriptors.last().getImplementationFactory()->createInstance(mock, false)}}; - resolver.createRestInstances(instances); - - EXPECT_EQ(instances.size(), 3); - EXPECT_TRUE(instances.isSealed()); - EXPECT_TRUE(instances.getInnerList()[0].isValid()); - EXPECT_TRUE(instances.getInnerList()[0].getAs()); - EXPECT_EQ(instances.getInnerList()[0].tryGetImplementation()->getTypeId(), typeid(TestInheritClass3)); - EXPECT_TRUE(instances.getInnerList()[1].isValid()); - EXPECT_TRUE(instances.getInnerList()[1].getAs()); - EXPECT_EQ(instances.getInnerList()[1].tryGetImplementation()->getTypeId(), typeid(TestInheritClass5)); - EXPECT_TRUE(instances.getInnerList()[2].isValid()); - EXPECT_TRUE(instances.getInnerList()[2].getAs()); - EXPECT_EQ(instances.getInnerList()[2].tryGetImplementation()->getTypeId(), typeid(TestInheritClass4)); -} - -TEST_F(ServiceInstanceResolverTest, ShouldCreateInstanceInPlace) -{ - ServiceProviderMock mock; - sb::di::details::ServiceInstanceCreator creator; - creator.setServiceProvider(mock); - const sb::di::details::ServiceDescriptorList descriptors{sb::di::ServiceDescriber::describeSingleton()}; - - const sb::di::details::ServiceInstancesResolver resolver{creator, descriptors}; - - const auto instance = resolver.createInstanceInPlace(); - - EXPECT_TRUE(instance); - EXPECT_TRUE(instance.isValid()); - EXPECT_TRUE(instance.getAs()); - EXPECT_EQ(instance.tryGetImplementation()->getTypeId(), typeid(TestClass1)); -} - -TEST_F(ServiceInstanceResolverTest, ShouldCreateInheritedInstanceInPlace) -{ - ServiceProviderMock mock; - sb::di::details::ServiceInstanceCreator creator; - creator.setServiceProvider(mock); - sb::di::details::ServiceDescriptorList descriptors{ - sb::di::ServiceDescriber::describeSingleton()}; - descriptors.add(sb::di::ServiceDescriber::describeSingleton()); - descriptors.add(sb::di::ServiceDescriber::describeSingleton()); - - const sb::di::details::ServiceInstancesResolver resolver{creator, descriptors}; - - const auto instance = resolver.createInstanceInPlace(); - - EXPECT_TRUE(instance); - EXPECT_TRUE(instance.isValid()); - EXPECT_TRUE(instance.getAs()); - EXPECT_EQ(instance.tryGetImplementation()->getTypeId(), typeid(TestInheritClass4)); -} - -TEST_F(ServiceInstanceResolverTest, ShouldCreateOneInstanceInPlace) -{ - ServiceProviderMock mock; - sb::di::details::ServiceInstanceCreator creator; - creator.setServiceProvider(mock); - const sb::di::details::ServiceDescriptorList descriptors{sb::di::ServiceDescriber::describeSingleton()}; - - const sb::di::details::ServiceInstancesResolver resolver{creator, descriptors}; - - const auto instances = resolver.createOneInstanceInPlace(); - - EXPECT_EQ(instances.size(), 1); - EXPECT_TRUE(instances.isSealed()); - EXPECT_TRUE(instances.getInnerList()[0].isValid()); - EXPECT_TRUE(instances.getInnerList()[0].getAs()); - EXPECT_EQ(instances.getInnerList()[0].tryGetImplementation()->getTypeId(), typeid(TestClass1)); -} - -TEST_F(ServiceInstanceResolverTest, ShouldCreateOneInheritedInstanceInPlace) -{ - ServiceProviderMock mock; - sb::di::details::ServiceInstanceCreator creator; - creator.setServiceProvider(mock); - sb::di::details::ServiceDescriptorList descriptors{ - sb::di::ServiceDescriber::describeSingleton()}; - descriptors.add(sb::di::ServiceDescriber::describeSingleton()); - descriptors.add(sb::di::ServiceDescriber::describeSingleton()); - - const sb::di::details::ServiceInstancesResolver resolver{creator, descriptors}; - - const auto instances = resolver.createOneInstanceInPlace(); - - EXPECT_EQ(instances.size(), 1); - EXPECT_FALSE(instances.isSealed()); - EXPECT_TRUE(instances.getInnerList()[0].isValid()); - EXPECT_TRUE(instances.getInnerList()[0].getAs()); - EXPECT_EQ(instances.getInnerList()[0].tryGetImplementation()->getTypeId(), typeid(TestInheritClass4)); -} - -TEST_F(ServiceInstanceResolverTest, ShouldCreateAllInstancesInPlace) -{ - ServiceProviderMock mock; - sb::di::details::ServiceInstanceCreator creator; - creator.setServiceProvider(mock); - const sb::di::details::ServiceDescriptorList descriptors{sb::di::ServiceDescriber::describeSingleton()}; - - const sb::di::details::ServiceInstancesResolver resolver{creator, descriptors}; - - const auto instances = resolver.createAllInstancesInPlace(); - - EXPECT_EQ(instances.size(), 1); - EXPECT_TRUE(instances.isSealed()); - EXPECT_TRUE(instances.getInnerList()[0].isValid()); - EXPECT_TRUE(instances.getInnerList()[0].getAs()); - EXPECT_EQ(instances.getInnerList()[0].tryGetImplementation()->getTypeId(), typeid(TestClass1)); -} - -TEST_F(ServiceInstanceResolverTest, ShouldCreateAllInheritedInstancesInPlace) -{ - ServiceProviderMock mock; - sb::di::details::ServiceInstanceCreator creator; - creator.setServiceProvider(mock); - sb::di::details::ServiceDescriptorList descriptors{ - sb::di::ServiceDescriber::describeSingleton()}; - descriptors.add(sb::di::ServiceDescriber::describeSingleton()); - descriptors.add(sb::di::ServiceDescriber::describeSingleton()); - - const sb::di::details::ServiceInstancesResolver resolver{creator, descriptors}; - - const auto instances = resolver.createAllInstancesInPlace(); - - EXPECT_EQ(instances.size(), 3); - EXPECT_TRUE(instances.isSealed()); - EXPECT_TRUE(instances.getInnerList()[0].isValid()); - EXPECT_TRUE(instances.getInnerList()[0].getAs()); - EXPECT_EQ(instances.getInnerList()[0].tryGetImplementation()->getTypeId(), typeid(TestInheritClass3)); - EXPECT_TRUE(instances.getInnerList()[1].isValid()); - EXPECT_TRUE(instances.getInnerList()[1].getAs()); - EXPECT_EQ(instances.getInnerList()[1].tryGetImplementation()->getTypeId(), typeid(TestInheritClass5)); - EXPECT_TRUE(instances.getInnerList()[2].isValid()); - EXPECT_TRUE(instances.getInnerList()[2].getAs()); - EXPECT_EQ(instances.getInnerList()[2].tryGetImplementation()->getTypeId(), typeid(TestInheritClass4)); -} - -TEST_F(ServiceInstanceResolverTest, ShouldCreateRestInheritedInstancesInPlace) -{ - ServiceProviderMock mock; - sb::di::details::ServiceInstanceCreator creator; - creator.setServiceProvider(mock); - sb::di::details::ServiceDescriptorList descriptors{ - sb::di::ServiceDescriber::describeSingleton()}; - descriptors.add(sb::di::ServiceDescriber::describeSingleton()); - descriptors.add(sb::di::ServiceDescriber::describeSingleton()); - - const sb::di::details::ServiceInstancesResolver resolver{creator, descriptors}; - - sb::di::details::ServiceInstanceList instances{ - sb::di::ServiceInstance{descriptors.last().getImplementationFactory()->createInstance(mock, true)}}; - resolver.createRestInstancesInPlace(instances); - - EXPECT_EQ(instances.size(), 3); - EXPECT_TRUE(instances.isSealed()); - EXPECT_TRUE(instances.getInnerList()[0].isValid()); - EXPECT_TRUE(instances.getInnerList()[0].getAs()); - EXPECT_EQ(instances.getInnerList()[0].tryGetImplementation()->getTypeId(), typeid(TestInheritClass3)); - EXPECT_TRUE(instances.getInnerList()[1].isValid()); - EXPECT_TRUE(instances.getInnerList()[1].getAs()); - EXPECT_EQ(instances.getInnerList()[1].tryGetImplementation()->getTypeId(), typeid(TestInheritClass5)); - EXPECT_TRUE(instances.getInnerList()[2].isValid()); - EXPECT_TRUE(instances.getInnerList()[2].getAs()); - EXPECT_EQ(instances.getInnerList()[2].tryGetImplementation()->getTypeId(), typeid(TestInheritClass4)); -} - -TEST_F(ServiceInstanceResolverTest, ShouldCreateAlias) -{ - ServiceProviderMock mock; - sb::di::details::ServiceInstanceCreator creator; - creator.setServiceProvider(mock); - sb::di::details::ServiceDescriptorList descriptors{ - sb::di::ServiceDescriber::describeAlias()}; - descriptors.add(sb::di::ServiceDescriber::describeAlias()); - descriptors.add(sb::di::ServiceDescriber::describeAlias()); - - const sb::di::details::ServiceInstancesResolver resolver{creator, descriptors}; - - TestInheritClass6 test; - const sb::di::ServiceInstance external{ - std::make_unique>(&test)}; - - const auto instance = resolver.createAlias(external); - - EXPECT_TRUE(instance); - EXPECT_TRUE(instance.isValid()); - EXPECT_TRUE(instance.getAs()); - EXPECT_EQ(instance.tryGetImplementation()->getTypeId(), typeid(TestInheritClass5)); -} - -TEST_F(ServiceInstanceResolverTest, ShouldCreateOneAlias) -{ - ServiceProviderMock mock; - sb::di::details::ServiceInstanceCreator creator; - creator.setServiceProvider(mock); - sb::di::details::ServiceDescriptorList descriptors{ - sb::di::ServiceDescriber::describeAlias()}; - descriptors.add(sb::di::ServiceDescriber::describeAlias()); - descriptors.add(sb::di::ServiceDescriber::describeAlias()); - - const sb::di::details::ServiceInstancesResolver resolver{creator, descriptors}; - - TestInheritClass6 test; - sb::di::ServiceInstance external{std::make_unique>(&test)}; - - const auto instances = resolver.createOneAlias(external); - - EXPECT_EQ(instances.size(), 1); - EXPECT_FALSE(instances.isSealed()); - EXPECT_TRUE(instances.getInnerList()[0].isValid()); - EXPECT_TRUE(instances.getInnerList()[0].getAs()); - EXPECT_EQ(instances.getInnerList()[0].tryGetImplementation()->getTypeId(), typeid(TestInheritClass5)); -} - -TEST_F(ServiceInstanceResolverTest, ShouldCreateAllAliases) -{ - ServiceProviderMock mock; - sb::di::details::ServiceInstanceCreator creator; - creator.setServiceProvider(mock); - sb::di::details::ServiceDescriptorList descriptors{ - sb::di::ServiceDescriber::describeAlias()}; - - const sb::di::details::ServiceInstancesResolver resolver{creator, descriptors}; - - TestInheritClass3 test3; - TestInheritClass4 test4; - TestInheritClass5 test5; - sb::di::details::ServiceInstanceList externals{ - sb::di::ServiceInstance{std::make_unique>(&test3)}}; - externals.add( - sb::di::ServiceInstance{std::make_unique>(&test4)}); - externals.add( - sb::di::ServiceInstance{std::make_unique>(&test5)}); - - const auto instances = resolver.createAllAliases(externals.getInnerList()); - - EXPECT_EQ(instances.size(), 3); - EXPECT_TRUE(instances.isSealed()); - EXPECT_TRUE(instances.getInnerList()[0].isValid()); - EXPECT_TRUE(instances.getInnerList()[0].getAs()); - EXPECT_EQ(instances.getInnerList()[0].tryGetImplementation()->getTypeId(), typeid(TestInheritClass2)); - EXPECT_TRUE(instances.getInnerList()[1].isValid()); - EXPECT_TRUE(instances.getInnerList()[1].getAs()); - EXPECT_EQ(instances.getInnerList()[1].tryGetImplementation()->getTypeId(), typeid(TestInheritClass2)); - EXPECT_TRUE(instances.getInnerList()[2].isValid()); - EXPECT_TRUE(instances.getInnerList()[2].getAs()); - EXPECT_EQ(instances.getInnerList()[2].tryGetImplementation()->getTypeId(), typeid(TestInheritClass2)); -} - -TEST_F(ServiceInstanceResolverTest, ShouldCreateRestAliases) -{ - ServiceProviderMock mock; - sb::di::details::ServiceInstanceCreator creator; - creator.setServiceProvider(mock); - sb::di::details::ServiceDescriptorList descriptors{ - sb::di::ServiceDescriber::describeAlias()}; - - const sb::di::details::ServiceInstancesResolver resolver{creator, descriptors}; - - TestInheritClass3 test3; - TestInheritClass4 test4; - TestInheritClass5 test5; - sb::di::details::ServiceInstanceList externals{ - sb::di::ServiceInstance{std::make_unique>(&test3)}}; - externals.add( - sb::di::ServiceInstance{std::make_unique>(&test4)}); - externals.add( - sb::di::ServiceInstance{std::make_unique>(&test5)}); - - sb::di::details::ServiceInstanceList instances{ - sb::di::ServiceInstance{std::make_unique>(&test5)}}; - - auto &_ = resolver.createRestAliases(externals.getInnerList(), instances); - - EXPECT_EQ(instances.size(), 3); - EXPECT_TRUE(instances.isSealed()); - EXPECT_TRUE(instances.getInnerList()[0].isValid()); - EXPECT_TRUE(instances.getInnerList()[0].getAs()); - EXPECT_EQ(instances.getInnerList()[0].tryGetImplementation()->getTypeId(), typeid(TestInheritClass2)); - EXPECT_TRUE(instances.getInnerList()[1].isValid()); - EXPECT_TRUE(instances.getInnerList()[1].getAs()); - EXPECT_EQ(instances.getInnerList()[1].tryGetImplementation()->getTypeId(), typeid(TestInheritClass2)); - EXPECT_TRUE(instances.getInnerList()[2].isValid()); - EXPECT_TRUE(instances.getInnerList()[2].getAs()); - EXPECT_EQ(instances.getInnerList()[2].tryGetImplementation()->getTypeId(), typeid(TestInheritClass2)); -} diff --git a/Tests/Unit/Core/ServiceInstancesCreatorTest.cpp b/Tests/Unit/Core/ServiceInstancesCreatorTest.cpp new file mode 100644 index 0000000..2c3319f --- /dev/null +++ b/Tests/Unit/Core/ServiceInstancesCreatorTest.cpp @@ -0,0 +1,299 @@ +#include +#include + +#include "../../Helpers/Classes/Basic.hpp" +#include "../../Helpers/Classes/CirularDependency.hpp" +#include "../../Helpers/Classes/Inherit.hpp" +#include "../../Helpers/Mocks/ServiceProviderMock.hpp" +#include +#include + +class ServiceInstancesCreatorTest : public testing::Test +{ + protected: + static void SetUpTestSuite() {} + + ServiceInstancesCreatorTest() {} + + void SetUp() override {} + + void TearDown() override {} + + ~ServiceInstancesCreatorTest() override = default; + + static void TearDownTestSuite() {} +}; + +TEST_F(ServiceInstancesCreatorTest, ShouldFailForNullProvider) +{ + ServiceProviderMock mock; + sb::di::details::ServiceInstancesCreator creator; + + const auto descriptor = sb::di::ServiceDescriber::describeSingleton(); + + EXPECT_THROW(creator.create(descriptor), sb::di::NullPointerException); +} + +TEST_F(ServiceInstancesCreatorTest, ShouldFailForInvalidInstance) +{ + ServiceProviderMock mock; + sb::di::details::ServiceInstancesCreator creator; + creator.setServiceProvider(mock); + + const auto descriptor = sb::di::ServiceDescriber::describeSingleton(nullptr); + + EXPECT_THROW(creator.create(descriptor), sb::di::InvalidServiceException); +} + +TEST_F(ServiceInstancesCreatorTest, ShouldFailFoWrongDescriptor) +{ + ServiceProviderMock mock; + sb::di::details::ServiceInstancesCreator creator; + creator.setServiceProvider(mock); + + const auto descriptor = sb::di::ServiceDescriber::describeAlias(); + + EXPECT_THROW(creator.create(descriptor), sb::di::InjectorException); +} + +TEST_F(ServiceInstancesCreatorTest, ShouldFailForCircularDependency) +{ + ServiceProviderMock mock; + sb::di::details::ServiceInstancesCreator creator; + creator.setServiceProvider(mock); + + EXPECT_CALL(mock.getMock(), tryGetInstance(sb::di::TypeId{typeid(CircularDependencyA)})) + .WillOnce(testing::Invoke([&](sb::di::TypeId typeId) { + const auto descriptor = sb::di::ServiceDescriber::describeSingleton(); + creator.create(descriptor); + return nullptr; + })); + + EXPECT_CALL(mock.getMock(), tryGetInstance(sb::di::TypeId{typeid(CircularDependencyB)})) + .WillOnce(testing::Invoke([&](sb::di::TypeId typeId) { + const auto descriptor = sb::di::ServiceDescriber::describeSingleton(); + creator.create(descriptor); + return nullptr; + })); + + const auto descriptor = sb::di::ServiceDescriber::describeSingleton(); + + EXPECT_THROW(creator.create(descriptor), sb::di::CircularDependencyException); +} + +TEST_F(ServiceInstancesCreatorTest, ShouldCreateInstance) +{ + ServiceProviderMock mock; + sb::di::details::ServiceInstancesCreator creator; + creator.setServiceProvider(mock); + + const auto instance = creator.create(sb::di::ServiceDescriber::describeSingleton()); + + EXPECT_TRUE(instance); + EXPECT_TRUE(instance.isValid()); + EXPECT_TRUE(instance.getAs()); + EXPECT_EQ(instance.tryGetImplementation()->getTypeId(), typeid(TestClass1)); +} + +TEST_F(ServiceInstancesCreatorTest, ShouldCreateInheritedInstance) +{ + ServiceProviderMock mock; + sb::di::details::ServiceInstancesCreator creator; + creator.setServiceProvider(mock); + + const auto instance = + creator.create(sb::di::ServiceDescriber::describeSingleton()); + + EXPECT_TRUE(instance); + EXPECT_TRUE(instance.isValid()); + EXPECT_TRUE(instance.getAs()); + EXPECT_EQ(instance.tryGetImplementation()->getTypeId(), typeid(TestInheritClass4)); +} + +TEST_F(ServiceInstancesCreatorTest, ShouldCreateAllInstances) +{ + ServiceProviderMock mock; + sb::di::details::ServiceInstancesCreator creator; + creator.setServiceProvider(mock); + + const sb::di::details::ServiceDescriptorList descriptors{sb::di::ServiceDescriber::describeSingleton()}; + const auto instances = creator.createAll(descriptors); + + EXPECT_EQ(instances.size(), 1); + EXPECT_FALSE(instances.isSealed()); + EXPECT_TRUE(instances[0].isValid()); + EXPECT_TRUE(instances[0].getAs()); + EXPECT_EQ(instances[0].tryGetImplementation()->getTypeId(), typeid(TestClass1)); +} + +TEST_F(ServiceInstancesCreatorTest, ShouldCreateAllInheritedInstances) +{ + ServiceProviderMock mock; + sb::di::details::ServiceInstancesCreator creator; + creator.setServiceProvider(mock); + + sb::di::details::ServiceDescriptorList descriptors{ + sb::di::ServiceDescriber::describeSingleton()}; + descriptors.add(sb::di::ServiceDescriber::describeSingleton()); + descriptors.add(sb::di::ServiceDescriber::describeSingleton()); + + const auto instances = creator.createAll(descriptors); + + EXPECT_EQ(instances.size(), 3); + EXPECT_FALSE(instances.isSealed()); + EXPECT_TRUE(instances[0].isValid()); + EXPECT_TRUE(instances[0].getAs()); + EXPECT_EQ(instances[0].tryGetImplementation()->getTypeId(), typeid(TestInheritClass3)); + EXPECT_TRUE(instances[1].isValid()); + EXPECT_TRUE(instances[1].getAs()); + EXPECT_EQ(instances[1].tryGetImplementation()->getTypeId(), typeid(TestInheritClass5)); + EXPECT_TRUE(instances[2].isValid()); + EXPECT_TRUE(instances[2].getAs()); + EXPECT_EQ(instances[2].tryGetImplementation()->getTypeId(), typeid(TestInheritClass4)); +} + +TEST_F(ServiceInstancesCreatorTest, ShouldCreateEmptyInstances) +{ + ServiceProviderMock mock; + sb::di::details::ServiceInstancesCreator creator; + creator.setServiceProvider(mock); + + const sb::di::details::ServiceDescriptorList descriptors; + const auto instances = creator.createAll(descriptors); + + EXPECT_TRUE(instances.empty()); + EXPECT_FALSE(instances.isSealed()); +} + +TEST_F(ServiceInstancesCreatorTest, ShouldCreateSkippedInheritedInstances) +{ + ServiceProviderMock mock; + sb::di::details::ServiceInstancesCreator creator; + creator.setServiceProvider(mock); + + sb::di::details::ServiceDescriptorList descriptors{ + sb::di::ServiceDescriber::describeSingleton()}; + descriptors.add(sb::di::ServiceDescriber::describeSingleton()); + descriptors.add(sb::di::ServiceDescriber::describeSingleton()); + + const auto instances = creator.createAll(descriptors, 1); + + EXPECT_EQ(instances.size(), 2); + EXPECT_FALSE(instances.isSealed()); + EXPECT_TRUE(instances[0].isValid()); + EXPECT_TRUE(instances[0].getAs()); + EXPECT_EQ(instances[0].tryGetImplementation()->getTypeId(), typeid(TestInheritClass3)); + EXPECT_TRUE(instances[1].isValid()); + EXPECT_TRUE(instances[1].getAs()); + EXPECT_EQ(instances[1].tryGetImplementation()->getTypeId(), typeid(TestInheritClass5)); +} + +TEST_F(ServiceInstancesCreatorTest, ShouldCreateInstanceInPlace) +{ + ServiceProviderMock mock; + sb::di::details::ServiceInstancesCreator creator; + creator.setServiceProvider(mock); + + const auto instance = creator.createInPlace(sb::di::ServiceDescriber::describeSingleton()); + + EXPECT_TRUE(instance); + EXPECT_TRUE(instance.isValid()); + EXPECT_TRUE(instance.getAs()); + EXPECT_EQ(instance.tryGetImplementation()->getTypeId(), typeid(TestClass1)); +} + +TEST_F(ServiceInstancesCreatorTest, ShouldCreateInheritedInstanceInPlace) +{ + ServiceProviderMock mock; + sb::di::details::ServiceInstancesCreator creator; + creator.setServiceProvider(mock); + + const auto instance = + creator.createInPlace(sb::di::ServiceDescriber::describeSingleton()); + + EXPECT_TRUE(instance); + EXPECT_TRUE(instance.isValid()); + EXPECT_TRUE(instance.getAs()); + EXPECT_EQ(instance.tryGetImplementation()->getTypeId(), typeid(TestInheritClass4)); +} + +TEST_F(ServiceInstancesCreatorTest, ShouldCreateAllInstancesInPlace) +{ + ServiceProviderMock mock; + sb::di::details::ServiceInstancesCreator creator; + creator.setServiceProvider(mock); + + const sb::di::details::ServiceDescriptorList descriptors{sb::di::ServiceDescriber::describeSingleton()}; + const auto instances = creator.createAllInPlace(descriptors); + + EXPECT_EQ(instances.size(), 1); + EXPECT_FALSE(instances.isSealed()); + EXPECT_TRUE(instances[0].isValid()); + EXPECT_TRUE(instances[0].getAs()); + EXPECT_EQ(instances[0].tryGetImplementation()->getTypeId(), typeid(TestClass1)); +} + +TEST_F(ServiceInstancesCreatorTest, ShouldCreateAllInheritedInstancesInPlace) +{ + ServiceProviderMock mock; + sb::di::details::ServiceInstancesCreator creator; + creator.setServiceProvider(mock); + + sb::di::details::ServiceDescriptorList descriptors{ + sb::di::ServiceDescriber::describeSingleton()}; + descriptors.add(sb::di::ServiceDescriber::describeSingleton()); + descriptors.add(sb::di::ServiceDescriber::describeSingleton()); + const auto instances = creator.createAllInPlace(descriptors); + + EXPECT_EQ(instances.size(), 3); + EXPECT_FALSE(instances.isSealed()); + EXPECT_TRUE(instances[0].isValid()); + EXPECT_TRUE(instances[0].getAs()); + EXPECT_EQ(instances[0].tryGetImplementation()->getTypeId(), typeid(TestInheritClass3)); + EXPECT_TRUE(instances[1].isValid()); + EXPECT_TRUE(instances[1].getAs()); + EXPECT_EQ(instances[1].tryGetImplementation()->getTypeId(), typeid(TestInheritClass5)); + EXPECT_TRUE(instances[2].isValid()); + EXPECT_TRUE(instances[2].getAs()); + EXPECT_EQ(instances[2].tryGetImplementation()->getTypeId(), typeid(TestInheritClass4)); +} + +TEST_F(ServiceInstancesCreatorTest, ShouldCreateSkippedInheritedInstancesInPlace) +{ + ServiceProviderMock mock; + sb::di::details::ServiceInstancesCreator creator; + creator.setServiceProvider(mock); + + sb::di::details::ServiceDescriptorList descriptors{ + sb::di::ServiceDescriber::describeSingleton()}; + descriptors.add(sb::di::ServiceDescriber::describeSingleton()); + descriptors.add(sb::di::ServiceDescriber::describeSingleton()); + + const auto instances = creator.createAll(descriptors, 1); + + EXPECT_EQ(instances.size(), 2); + EXPECT_FALSE(instances.isSealed()); + EXPECT_TRUE(instances[0].isValid()); + EXPECT_TRUE(instances[0].getAs()); + EXPECT_EQ(instances[0].tryGetImplementation()->getTypeId(), typeid(TestInheritClass3)); + EXPECT_TRUE(instances[1].isValid()); + EXPECT_TRUE(instances[1].getAs()); + EXPECT_EQ(instances[1].tryGetImplementation()->getTypeId(), typeid(TestInheritClass5)); +} + +TEST_F(ServiceInstancesCreatorTest, ShouldNotCreateSkippedInheritedInstancesInPlace) +{ + ServiceProviderMock mock; + sb::di::details::ServiceInstancesCreator creator; + creator.setServiceProvider(mock); + + sb::di::details::ServiceDescriptorList descriptors{ + sb::di::ServiceDescriber::describeSingleton()}; + descriptors.add(sb::di::ServiceDescriber::describeSingleton()); + descriptors.add(sb::di::ServiceDescriber::describeSingleton()); + + const auto instances = creator.createAll(descriptors, 5); + + EXPECT_TRUE(instances.empty()); + EXPECT_FALSE(instances.isSealed()); +} diff --git a/Tests/Unit/Factories/ExternalServiceFactoryTest.cpp b/Tests/Unit/Factories/ExternalServiceFactoryTest.cpp index cf07b21..d1ebd1d 100644 --- a/Tests/Unit/Factories/ExternalServiceFactoryTest.cpp +++ b/Tests/Unit/Factories/ExternalServiceFactoryTest.cpp @@ -2,7 +2,7 @@ #include "../../Helpers/Classes/Basic.hpp" #include "../../Helpers/Mocks/ServiceProviderMock.hpp" -#include "SevenBit/DI/Details/Factories/ExternalServiceFactory.hpp" +#include class ExternalServiceFactoryTest : public testing::Test { diff --git a/Tests/Unit/Factories/ServiceFactoryTest.cpp b/Tests/Unit/Factories/ServiceFactoryTest.cpp index 9397b50..f7314ae 100644 --- a/Tests/Unit/Factories/ServiceFactoryTest.cpp +++ b/Tests/Unit/Factories/ServiceFactoryTest.cpp @@ -4,7 +4,7 @@ #include "../../Helpers/Classes/Complex.hpp" #include "../../Helpers/Classes/Dependencies.hpp" #include "../../Helpers/Mocks/ServiceProviderMock.hpp" -#include "SevenBit/DI/Details/Factories/ServiceFactory.hpp" +#include class ServiceFactoryTest : public testing::Test { @@ -191,8 +191,7 @@ TEST_F(ServiceFactoryTest, ShouldCreateDependencyUniq1Service) EXPECT_TRUE(instance); EXPECT_TRUE(instance->isValid()); EXPECT_TRUE(instance->get()); - EXPECT_TRUE( - dynamic_cast *>(instance.get())); + EXPECT_TRUE(dynamic_cast *>(instance.get())); } TEST_F(ServiceFactoryTest, ShouldCreateDependencyUniq2Service) @@ -212,8 +211,7 @@ TEST_F(ServiceFactoryTest, ShouldCreateDependencyUniq2Service) EXPECT_TRUE(instance); EXPECT_TRUE(instance->isValid()); EXPECT_TRUE(instance->get()); - EXPECT_TRUE( - dynamic_cast *>(instance.get())); + EXPECT_TRUE(dynamic_cast *>(instance.get())); } TEST_F(ServiceFactoryTest, ShouldCreateDependencyVec1Service) @@ -265,7 +263,7 @@ TEST_F(ServiceFactoryTest, ShouldCreateDependencyVec3Service) sb::di::OneOrList result{std::move(test1)}; EXPECT_CALL(mock.getMock(), tryCreateInstances(sb::di::TypeId{typeid(TestDependencyClass)})) - .WillOnce(testing::Return(std::make_optional(std::move(result)))); + .WillOnce(testing::Return(std::move(result))); const sb::di::details::ServiceFactory factory; @@ -287,7 +285,7 @@ TEST_F(ServiceFactoryTest, ShouldCreateDependencyVec4Service) sb::di::OneOrList result{std::move(test1)}; EXPECT_CALL(mock.getMock(), tryCreateInstances(sb::di::TypeId{typeid(TestDependencyClass)})) - .WillOnce(testing::Return(std::make_optional(std::move(result)))); + .WillOnce(testing::Return(std::move(result))); const sb::di::details::ServiceFactory factory; diff --git a/Tests/Unit/Factories/ServiceFcnFactoryTest.cpp b/Tests/Unit/Factories/ServiceFcnFactoryTest.cpp index ab5c663..99673d8 100644 --- a/Tests/Unit/Factories/ServiceFcnFactoryTest.cpp +++ b/Tests/Unit/Factories/ServiceFcnFactoryTest.cpp @@ -4,7 +4,7 @@ #include "../../Helpers/Classes/Basic.hpp" #include "../../Helpers/Classes/Dependencies.hpp" #include "../../Helpers/Mocks/ServiceProviderMock.hpp" -#include "SevenBit/DI/Details/Factories/ServiceFcnFactory.hpp" +#include class ServiceFcnFactoryTest : public testing::Test { @@ -212,8 +212,7 @@ TEST_F(ServiceFcnFactoryTest, ShouldCreateDependencyUniq1Service) EXPECT_TRUE(instance); EXPECT_TRUE(instance->isValid()); EXPECT_TRUE(instance->get()); - EXPECT_TRUE( - dynamic_cast *>(instance.get())); + EXPECT_TRUE(dynamic_cast *>(instance.get())); } TEST_F(ServiceFcnFactoryTest, ShouldCreateDependencyUniq2Service) @@ -235,8 +234,7 @@ TEST_F(ServiceFcnFactoryTest, ShouldCreateDependencyUniq2Service) EXPECT_TRUE(instance); EXPECT_TRUE(instance->isValid()); EXPECT_TRUE(instance->get()); - EXPECT_TRUE( - dynamic_cast *>(instance.get())); + EXPECT_TRUE(dynamic_cast *>(instance.get())); } TEST_F(ServiceFcnFactoryTest, ShouldCreateDependencyVec1Service) @@ -290,7 +288,7 @@ TEST_F(ServiceFcnFactoryTest, ShouldCreateDependencyVec3Service) sb::di::OneOrList result{std::move(test1)}; EXPECT_CALL(mock.getMock(), tryCreateInstances(sb::di::TypeId{typeid(TestDependencyClass)})) - .WillOnce(testing::Return(std::make_optional(std::move(result)))); + .WillOnce(testing::Return(std::move(result))); const sb::di::details::ServiceFcnFactory factory{ [&](std::vector> ob) { return TestDependencyVecClass3(std::move(ob)); }}; @@ -313,12 +311,11 @@ TEST_F(ServiceFcnFactoryTest, ShouldCreateDependencyVec4Service) sb::di::OneOrList result{std::move(test1)}; EXPECT_CALL(mock.getMock(), tryCreateInstances(sb::di::TypeId{typeid(TestDependencyClass)})) - .WillOnce(testing::Return(std::make_optional(std::move(result)))); + .WillOnce(testing::Return(std::move(result))); - const sb::di::details::ServiceFcnFactory factory{ - [&](const std::vector> ob) { - return std::make_unique(std::vector>{}); - }}; + const sb::di::details::ServiceFcnFactory factory{[&](const std::vector> ob) { + return std::make_unique(std::vector>{}); + }}; const auto instance = factory.createInstance(mock, true); diff --git a/Tests/Unit/Helpers/CircularDependencyGuardTest.cpp b/Tests/Unit/Helpers/CircularDependencyGuardTest.cpp index 5a6111f..2106f22 100644 --- a/Tests/Unit/Helpers/CircularDependencyGuardTest.cpp +++ b/Tests/Unit/Helpers/CircularDependencyGuardTest.cpp @@ -1,8 +1,8 @@ #include #include "../../Helpers/Classes/Basic.hpp" -#include "SevenBit/DI/Details/Helpers/CircularDependencyGuard.hpp" -#include "SevenBit/DI/Exceptions.hpp" +#include +#include class CircularDependencyGuardTest : public testing::Test { diff --git a/Tests/Unit/Helpers/CtorInjectorTest.cpp b/Tests/Unit/Helpers/CtorInjectorTest.cpp index d2f50b0..0c83131 100644 --- a/Tests/Unit/Helpers/CtorInjectorTest.cpp +++ b/Tests/Unit/Helpers/CtorInjectorTest.cpp @@ -2,8 +2,8 @@ #include "../../Helpers/Classes/Dependencies.hpp" #include "../../Helpers/Mocks/ServiceProviderMock.hpp" -#include "SevenBit/DI/Details/Helpers/CtorInjector.hpp" -#include "SevenBit/DI/Details/Services/InPlaceService.hpp" +#include +#include class CtorInjectorTest : public testing::Test { diff --git a/Tests/Unit/Helpers/FunctorInjectorTest.cpp b/Tests/Unit/Helpers/FunctorInjectorTest.cpp index 3ec1eb2..ae848e9 100644 --- a/Tests/Unit/Helpers/FunctorInjectorTest.cpp +++ b/Tests/Unit/Helpers/FunctorInjectorTest.cpp @@ -2,8 +2,8 @@ #include "../../Helpers/Classes/Dependencies.hpp" #include "../../Helpers/Mocks/ServiceProviderMock.hpp" -#include "SevenBit/DI/Details/Helpers/FunctorInjector.hpp" -#include "SevenBit/DI/Details/Services/InPlaceService.hpp" +#include +#include class FunctorInjectorTest : public testing::Test { diff --git a/Tests/Unit/Helpers/ScopeGuardTest.cpp b/Tests/Unit/Helpers/ScopeGuardTest.cpp index 4b61172..349a2f2 100644 --- a/Tests/Unit/Helpers/ScopeGuardTest.cpp +++ b/Tests/Unit/Helpers/ScopeGuardTest.cpp @@ -1,8 +1,8 @@ #include #include "../../Helpers/Classes/Basic.hpp" -#include "SevenBit/DI/Details/Helpers/ScopedGuard.hpp" -#include "SevenBit/DI/Exceptions.hpp" +#include +#include class ScopeGuardTest : public testing::Test { diff --git a/Tests/Unit/Helpers/ServiceGetterTest.cpp b/Tests/Unit/Helpers/ServiceGetterTest.cpp index a631d0b..5469993 100644 --- a/Tests/Unit/Helpers/ServiceGetterTest.cpp +++ b/Tests/Unit/Helpers/ServiceGetterTest.cpp @@ -2,9 +2,9 @@ #include "../../Helpers/Classes/Dependencies.hpp" #include "../../Helpers/Mocks/ServiceProviderMock.hpp" -#include "SevenBit/DI/Details/Helpers/ServiceGetter.hpp" -#include "SevenBit/DI/Details/Services/InPlaceService.hpp" -#include "SevenBit/DI/Details/Services/UniquePtrService.hpp" +#include +#include +#include class ServiceGetterTest : public testing::Test { @@ -125,7 +125,7 @@ TEST_F(ServiceGetterTest, ShouldGetDependencyVec3Service) sb::di::OneOrList result{std::move(test1)}; EXPECT_CALL(mock.getMock(), tryCreateInstances(sb::di::TypeId{typeid(TestDependencyClass)})) - .WillOnce(testing::Return(std::make_optional(std::move(result)))); + .WillOnce(testing::Return(std::move(result))); auto act = [&] { std::vector> instance = diff --git a/Tests/Unit/OneOrListTest.cpp b/Tests/Unit/OneOrListTest.cpp index 619cbd3..4b48f82 100644 --- a/Tests/Unit/OneOrListTest.cpp +++ b/Tests/Unit/OneOrListTest.cpp @@ -1,6 +1,6 @@ #include -#include "SevenBit/DI/OneOrList.hpp" +#include class OneOrListTest : public testing::Test { @@ -18,6 +18,23 @@ class OneOrListTest : public testing::Test static void TearDownTestSuite() {} }; +TEST_F(OneOrListTest, ShouldCreateUninitialized) +{ + const sb::di::OneOrList list; + + EXPECT_TRUE(list.isUninitialized()); + EXPECT_TRUE(list.empty()); +} + +TEST_F(OneOrListTest, ShouldCheck) +{ + sb::di::OneOrList list; + + EXPECT_FALSE(list); + list.add(1); + EXPECT_TRUE(list); +} + TEST_F(OneOrListTest, ShouldCreateSingle) { sb::di::OneOrList list{2}; @@ -49,8 +66,9 @@ TEST_F(OneOrListTest, ShouldMove) TEST_F(OneOrListTest, ShouldAdd) { - sb::di::OneOrList list{2}; + sb::di::OneOrList list; + list.add(2); list.add(3); list.add(4); @@ -60,6 +78,25 @@ TEST_F(OneOrListTest, ShouldAdd) EXPECT_EQ(list[2], 4); } +TEST_F(OneOrListTest, ShouldAddList) +{ + sb::di::OneOrList list; + + list.add(2); + list.add(3); + list.add(4); + + sb::di::OneOrList list2; + list2.add(5); + list2.addList(std::move(list)); + + EXPECT_TRUE(list.isList()); + EXPECT_EQ(list2[0], 5); + EXPECT_EQ(list2[1], 2); + EXPECT_EQ(list2[2], 3); + EXPECT_EQ(list2[3], 4); +} + TEST_F(OneOrListTest, ShouldGetFirst) { sb::di::OneOrList list{2}; @@ -104,7 +141,10 @@ TEST_F(OneOrListTest, ShouldGetIndexed) TEST_F(OneOrListTest, ShouldGetSize) { - sb::di::OneOrList list{2}; + sb::di::OneOrList list; + + EXPECT_EQ(list.size(), 0); + list.add(2); EXPECT_EQ(list.size(), 1); @@ -119,7 +159,11 @@ TEST_F(OneOrListTest, ShouldGetSize) TEST_F(OneOrListTest, ShouldGetEmpty) { - sb::di::OneOrList list{2}; + sb::di::OneOrList list; + + EXPECT_TRUE(list.empty()); + + list.add(2); EXPECT_FALSE(list.empty()); @@ -197,6 +241,22 @@ TEST_F(OneOrListTest, ShouldTryGetAsSingle) EXPECT_FALSE(list.tryGetAsSingle()); } +TEST_F(OneOrListTest, ShouldClear) +{ + sb::di::OneOrList list{2}; + EXPECT_FALSE(list.empty()); + + list.clear(); + EXPECT_TRUE(list.empty()); + + list.add(2); + list.add(2); + EXPECT_FALSE(list.empty()); + + list.clear(); + EXPECT_TRUE(list.empty()); +} + TEST_F(OneOrListTest, ShouldForEach) { sb::di::OneOrList list{2}; diff --git a/Tests/Unit/ServiceCollectionTest.cpp b/Tests/Unit/ServiceCollectionTest.cpp index c85370d..60e8787 100644 --- a/Tests/Unit/ServiceCollectionTest.cpp +++ b/Tests/Unit/ServiceCollectionTest.cpp @@ -5,7 +5,7 @@ #include "../Helpers/Classes/Basic.hpp" #include "../Helpers/Classes/Complex.hpp" #include "../Helpers/Classes/Inherit.hpp" -#include "SevenBit/DI/ServiceCollection.hpp" +#include class ServiceCollectionTest : public testing::Test { @@ -133,8 +133,6 @@ TEST_F(ServiceCollectionTest, ShouldGetWithIndexOperator) EXPECT_EQ(four.getLifeTime(), sb::di::ServiceLifeTime::scoped()); EXPECT_EQ(four.getServiceTypeId(), typeid(TestInheritClass1)); EXPECT_EQ(four.getImplementationTypeId(), typeid(TestInheritClass5)); - - EXPECT_ANY_THROW(services[10]); } TEST_F(ServiceCollectionTest, ShouldGetSize) diff --git a/Tests/Unit/ServiceDescriberTest.cpp b/Tests/Unit/ServiceDescriberTest.cpp index 641d0b5..2a6e85f 100644 --- a/Tests/Unit/ServiceDescriberTest.cpp +++ b/Tests/Unit/ServiceDescriberTest.cpp @@ -3,9 +3,9 @@ #include "../Helpers/Classes/Basic.hpp" #include "../Helpers/Classes/Inherit.hpp" -#include "SevenBit/DI/Exceptions.hpp" -#include "SevenBit/DI/ServiceDescriber.hpp" -#include "SevenBit/DI/ServiceProvider.hpp" +#include +#include +#include class ServiceDescriberTest : public testing::Test { diff --git a/Tests/Unit/ServiceDescriptorTest.cpp b/Tests/Unit/ServiceDescriptorTest.cpp index bb2846f..3fbedc1 100644 --- a/Tests/Unit/ServiceDescriptorTest.cpp +++ b/Tests/Unit/ServiceDescriptorTest.cpp @@ -3,8 +3,8 @@ #include "../Helpers/Classes/Basic.hpp" #include "../Helpers/Classes/Complex.hpp" -#include "SevenBit/DI/Details/Factories/ServiceFactory.hpp" -#include "SevenBit/DI/ServiceDescriptor.hpp" +#include +#include class ServiceDescriptorTest : public testing::Test { diff --git a/Tests/Unit/ServiceInstanceTest.cpp b/Tests/Unit/ServiceInstanceTest.cpp index 839fe9f..e4524b8 100644 --- a/Tests/Unit/ServiceInstanceTest.cpp +++ b/Tests/Unit/ServiceInstanceTest.cpp @@ -1,9 +1,9 @@ #include #include "../Helpers/Classes/Basic.hpp" -#include "SevenBit/DI/Details/Services/InPlaceService.hpp" -#include "SevenBit/DI/Exceptions.hpp" -#include "SevenBit/DI/ServiceInstance.hpp" +#include +#include +#include class ServiceInstanceTest : public testing::Test { diff --git a/Tests/Unit/ServiceLifeTimeTest.cpp b/Tests/Unit/ServiceLifeTimeTest.cpp index 8ebf7f5..13883a0 100644 --- a/Tests/Unit/ServiceLifeTimeTest.cpp +++ b/Tests/Unit/ServiceLifeTimeTest.cpp @@ -1,6 +1,6 @@ #include -#include "SevenBit/DI/ServiceLifeTimes.hpp" +#include class ServiceLifeTime : public testing::Test { diff --git a/Tests/Unit/ServiceProviderTest.cpp b/Tests/Unit/ServiceProviderTest.cpp index 7b596be..0669b51 100644 --- a/Tests/Unit/ServiceProviderTest.cpp +++ b/Tests/Unit/ServiceProviderTest.cpp @@ -1,7 +1,7 @@ #include -#include "SevenBit/DI/Details/Core/ServiceInstanceProviderRoot.hpp" -#include "SevenBit/DI/ServiceProvider.hpp" +#include +#include class ServiceProviderTest : public testing::Test { diff --git a/Tests/Unit/Services/AliasServiceTest.cpp b/Tests/Unit/Services/AliasServiceTest.cpp index 41ca9e1..20b84c7 100644 --- a/Tests/Unit/Services/AliasServiceTest.cpp +++ b/Tests/Unit/Services/AliasServiceTest.cpp @@ -1,8 +1,8 @@ #include #include "../../Helpers/Classes/Basic.hpp" -#include "SevenBit/DI/Details/Services/AliasService.hpp" -#include "SevenBit/DI/Exceptions.hpp" +#include +#include class AliasServiceTest : public testing::Test { diff --git a/Tests/Unit/Services/ExternalServiceTest.cpp b/Tests/Unit/Services/ExternalServiceTest.cpp index 99b5993..ae74afe 100644 --- a/Tests/Unit/Services/ExternalServiceTest.cpp +++ b/Tests/Unit/Services/ExternalServiceTest.cpp @@ -1,8 +1,8 @@ #include #include "../../Helpers/Classes/Basic.hpp" -#include "SevenBit/DI/Details/Services/ExternalService.hpp" -#include "SevenBit/DI/Exceptions.hpp" +#include +#include class ExternalServiceTest : public testing::Test { diff --git a/Tests/Unit/Services/InPlaceServiceTest.cpp b/Tests/Unit/Services/InPlaceServiceTest.cpp index cb46d26..438f187 100644 --- a/Tests/Unit/Services/InPlaceServiceTest.cpp +++ b/Tests/Unit/Services/InPlaceServiceTest.cpp @@ -2,8 +2,8 @@ #include #include "../../Helpers/Classes/Basic.hpp" -#include "SevenBit/DI/Details/Services/InPlaceService.hpp" -#include "SevenBit/DI/Exceptions.hpp" +#include +#include class InPlaceServiceTest : public testing::Test { diff --git a/Tests/Unit/Services/UniquePtrServiceTest.cpp b/Tests/Unit/Services/UniquePtrServiceTest.cpp index 4922a55..3817a0a 100644 --- a/Tests/Unit/Services/UniquePtrServiceTest.cpp +++ b/Tests/Unit/Services/UniquePtrServiceTest.cpp @@ -2,8 +2,8 @@ #include #include "../../Helpers/Classes/Basic.hpp" -#include "SevenBit/DI/Details/Services/UniquePtrService.hpp" -#include "SevenBit/DI/Exceptions.hpp" +#include +#include class UniquePtrServiceTest : public testing::Test { diff --git a/Tests/Unit/Utils/CastTest.cpp b/Tests/Unit/Utils/CastTest.cpp index 8ef8ec7..cf57e39 100644 --- a/Tests/Unit/Utils/CastTest.cpp +++ b/Tests/Unit/Utils/CastTest.cpp @@ -1,8 +1,8 @@ #include #include "../../Helpers/Classes/MultiInherit.hpp" -#include "SevenBit/DI/Details/Services/InPlaceService.hpp" -#include "SevenBit/DI/Details/Utils/Cast.hpp" +#include +#include class CastTest : public testing::Test { diff --git a/Tests/Unit/Utils/CheckTest.cpp b/Tests/Unit/Utils/CheckTest.cpp index ecb65f4..38d1e6d 100644 --- a/Tests/Unit/Utils/CheckTest.cpp +++ b/Tests/Unit/Utils/CheckTest.cpp @@ -1,6 +1,6 @@ #include -#include "SevenBit/DI/Details/Utils/Check.hpp" +#include class CheckTest : public testing::Test { diff --git a/Tests/Unit/Utils/CtorParamsNumberTest.cpp b/Tests/Unit/Utils/CtorParamsNumberTest.cpp index 07929ef..8589212 100644 --- a/Tests/Unit/Utils/CtorParamsNumberTest.cpp +++ b/Tests/Unit/Utils/CtorParamsNumberTest.cpp @@ -1,7 +1,7 @@ #include #include "../../Helpers/Classes/Complex.hpp" -#include "SevenBit/DI/Details/Utils/CtorParamsNumber.hpp" +#include class CtorParamsNumberTest : public testing::Test { diff --git a/Tests/Unit/Utils/MetaTest.cpp b/Tests/Unit/Utils/MetaTest.cpp index ba1d058..2ed9793 100644 --- a/Tests/Unit/Utils/MetaTest.cpp +++ b/Tests/Unit/Utils/MetaTest.cpp @@ -2,7 +2,7 @@ #include "../../Helpers/Classes/Complex.hpp" #include "../../Helpers/Classes/MultiInherit.hpp" -#include "SevenBit/DI/Details/Utils/Meta.hpp" +#include class MetaTest : public testing::Test { diff --git a/Tests/Unit/Utils/RequireDescriptorTest.cpp b/Tests/Unit/Utils/RequireDescriptorTest.cpp index 639dd48..8527aed 100644 --- a/Tests/Unit/Utils/RequireDescriptorTest.cpp +++ b/Tests/Unit/Utils/RequireDescriptorTest.cpp @@ -2,9 +2,9 @@ #include "../../Helpers/Classes/Basic.hpp" #include "../../Helpers/Classes/Inherit.hpp" -#include "SevenBit/DI/Details/Utils/RequireDescriptor.hpp" -#include "SevenBit/DI/Exceptions.hpp" -#include "SevenBit/DI/ServiceDescriber.hpp" +#include +#include +#include class RequireDescriptorTest : public testing::Test { diff --git a/Tests/Unit/Utils/RequireInstanceTest.cpp b/Tests/Unit/Utils/RequireInstanceTest.cpp index 06a5f1d..2c163c1 100644 --- a/Tests/Unit/Utils/RequireInstanceTest.cpp +++ b/Tests/Unit/Utils/RequireInstanceTest.cpp @@ -1,12 +1,12 @@ #include #include "../../Helpers/Classes/Basic.hpp" -#include "SevenBit/DI/Details/Services/ExternalService.hpp" -#include "SevenBit/DI/Details/Services/InPlaceService.hpp" -#include "SevenBit/DI/Details/Services/UniquePtrService.hpp" -#include "SevenBit/DI/Details/Utils/RequireInstance.hpp" -#include "SevenBit/DI/Exceptions.hpp" -#include "SevenBit/DI/ServiceDescriber.hpp" +#include +#include +#include +#include +#include +#include class RequireInstanceTest : public testing::Test { diff --git a/Tests/Unit/Utils/RequireTest.cpp b/Tests/Unit/Utils/RequireTest.cpp index 2fcb34c..9d5e9ac 100644 --- a/Tests/Unit/Utils/RequireTest.cpp +++ b/Tests/Unit/Utils/RequireTest.cpp @@ -1,8 +1,8 @@ #include #include "../../Helpers/Classes/Basic.hpp" -#include "SevenBit/DI/Details/Utils/Require.hpp" -#include "SevenBit/DI/Exceptions.hpp" +#include +#include class RequireTest : public testing::Test {