diff --git a/mioc/include/mioc/ServiceContainer.h b/mioc/include/mioc/ServiceContainer.h index cc6963d..db67615 100644 --- a/mioc/include/mioc/ServiceContainer.h +++ b/mioc/include/mioc/ServiceContainer.h @@ -45,13 +45,13 @@ class ServiceContainer final // Resolve registered service. // nullptr returned if service not registered. template - std::shared_ptr Resolve() const + ServicePtr Resolve() const { auto typeId = _GetTypeId(); auto it = _services.find(typeId); if (it != _services.end()) { - auto factory = std::static_pointer_cast>(it->second); + auto factory = std::static_pointer_cast>(it->second); return factory->Resolve(); } return nullptr; @@ -61,7 +61,7 @@ class ServiceContainer final // Register a singleton instance. // Will replace old registrations silently. template - ServiceContainer* AddSingleton(std::shared_ptr singleton) + ServiceContainer* AddSingleton(ServicePtr singleton) { // std::map::emplace will not replace old value if key already presents. _services[_GetTypeId()] = std::make_shared>(singleton); @@ -76,10 +76,9 @@ class ServiceContainer final if (_lazy) { _AddSingletonServiceFactory( - std::function(std::shared_ptr... args)>( - [](std::shared_ptr... args) -> std::shared_ptr - { - return std::make_shared(std::forward>(args)...); + std::function(ServicePtr... args)>( + [](ServicePtr... args) -> ServicePtr { + return std::make_shared(std::forward>(args)...); })); } else @@ -96,10 +95,9 @@ class ServiceContainer final ServiceContainer* AddTransient() { _AddTransientServiceFactory( - std::function(std::shared_ptr... args)>( - [](std::shared_ptr... args) -> std::shared_ptr - { - return std::make_shared(std::forward>(args)...); + std::function(std::shared_ptr... args)>( + [](ServicePtr... args) -> ServicePtr { + return std::make_shared(std::forward>(args)...); })); return this; @@ -118,28 +116,27 @@ class ServiceContainer final // Low level registration. template void _AddTransientServiceFactory( - std::function(std::shared_ptr... dependencies)> factory) + std::function(ServicePtr... dependencies)> factory) { _services[_GetTypeId()] = - std::make_shared>([=] { return factory(Resolve()...); }); + std::make_shared>([=] { return factory(Resolve()...); }); } template void _AddSingletonServiceFactory( - std::function(std::shared_ptr... dependencies)> factory) + std::function(ServicePtr... dependencies)> factory) { _services[_GetTypeId()] = - std::make_shared>([=] - { - return factory(Resolve()...); + std::make_shared>([=] { + return factory(Resolve()...); }); } private: static int _nextTypeId; - std::map> _services; + std::map> _services; bool _lazy; }; diff --git a/mioc/include/mioc/ServiceFactory.h b/mioc/include/mioc/ServiceFactory.h index aa38731..17ab552 100644 --- a/mioc/include/mioc/ServiceFactory.h +++ b/mioc/include/mioc/ServiceFactory.h @@ -13,42 +13,51 @@ MIOC_BEGIN // Abstract representation of service factory. -class IServiceFactory +class ServiceFactory { public: // A simple trick to make a class abstract. - virtual ~IServiceFactory() = 0; + virtual ~ServiceFactory() = 0; }; -inline IServiceFactory::~IServiceFactory() = default; +inline ServiceFactory::~ServiceFactory() = default; + + +template +using ServicePtr = std::shared_ptr; template -using ServiceProvider = std::function()>; +using ServiceProvider = std::function()>; // Transient service factory will create a new instance every time. template -class ServiceFactory : public IServiceFactory +class TransientServiceFactory : public ServiceFactory { public: - explicit ServiceFactory(const ServiceProvider& provider) + explicit TransientServiceFactory(const ServiceProvider& provider) : _provider(provider) { } + explicit TransientServiceFactory(ServiceProvider&& provider) + : _provider(std::move(provider)) + { + } + - ServiceFactory(const ServiceFactory&) = default; - ServiceFactory& operator=(const ServiceFactory&) = default; + TransientServiceFactory(const TransientServiceFactory&) = default; + TransientServiceFactory& operator=(const TransientServiceFactory&) = default; - ServiceFactory(ServiceFactory&& other) noexcept + TransientServiceFactory(TransientServiceFactory&& other) noexcept { _provider = std::move(other._provider); } - ServiceFactory& operator=(ServiceFactory&& other) noexcept + TransientServiceFactory& operator=(TransientServiceFactory&& other) noexcept { if (this != &other) { @@ -58,7 +67,7 @@ class ServiceFactory : public IServiceFactory } - ~ServiceFactory() override = default; + ~TransientServiceFactory() override = default; virtual std::shared_ptr Resolve() @@ -68,7 +77,7 @@ class ServiceFactory : public IServiceFactory protected: // Used by SingletonServiceFactory when instance is directly provided. - ServiceFactory() = default; + TransientServiceFactory() = default; private: ServiceProvider _provider; @@ -77,17 +86,27 @@ class ServiceFactory : public IServiceFactory // Singleton service factory will create only one instance. template -class SingletonServiceFactory final : public ServiceFactory +class SingletonServiceFactory final : public TransientServiceFactory { public: explicit SingletonServiceFactory(const ServiceProvider& provider) - : ServiceFactory(provider) + : TransientServiceFactory(provider) { } + explicit SingletonServiceFactory(ServiceProvider&& provider) + : TransientServiceFactory(std::move(provider)) + { + } + + + explicit SingletonServiceFactory(const ServicePtr& instance) + { + _instance = instance; + } - explicit SingletonServiceFactory(std::shared_ptr instance) - : ServiceFactory() + explicit SingletonServiceFactory(ServicePtr&& instance) + : TransientServiceFactory() { _instance = std::move(instance); } @@ -98,7 +117,7 @@ class SingletonServiceFactory final : public ServiceFactory SingletonServiceFactory(SingletonServiceFactory&& other) noexcept - : ServiceFactory(std::move(other)) + : TransientServiceFactory(std::move(other)) { _instance = std::move(other._instance); } @@ -108,7 +127,7 @@ class SingletonServiceFactory final : public ServiceFactory { if (this != &other) { - ServiceFactory::operator=(std::move(other)); + TransientServiceFactory::operator=(std::move(other)); _instance = std::move(other._instance); } return *this; @@ -122,14 +141,14 @@ class SingletonServiceFactory final : public ServiceFactory { if (_instance == nullptr) { - _instance = ServiceFactory::Resolve(); + _instance = TransientServiceFactory::Resolve(); } return _instance; } private: - std::shared_ptr _instance; + ServicePtr _instance; };