#pragma region CPL License /* Nuclex Native Framework Copyright (C) 2002-2023 Nuclex Development Labs This library is free software; you can redistribute it and/or modify it under the terms of the IBM Common Public License as published by the IBM Corporation; either version 1.0 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the IBM Common Public License for more details. You should have received a copy of the IBM Common Public License along with this library */ #pragma endregion // CPL License #ifndef NUCLEX_SUPPORT_SERVICES_SERVICEPROVIDER_H #define NUCLEX_SUPPORT_SERVICES_SERVICEPROVIDER_H #include "Nuclex/Support/Config.h" #include // for std::shared_ptr #include // for std::decay, std::type_info #include // for std::any namespace Nuclex { namespace Support { namespace Services { // ------------------------------------------------------------------------------------------- // /// Provides services to the application /// /// This is an interface through which services can be looked up. It is either used /// manually (but beware of the service locator anti-pattern!) or as part of /// a dependency injection framework. /// class NUCLEX_SUPPORT_TYPE ServiceProvider { /// Destroys the service provider and frees all resources public: NUCLEX_SUPPORT_API virtual ~ServiceProvider() = default; /// Looks up the specified service /// Type of service that will be looked up /// /// The specified service as a shared_ptr wrapped in an /// public: template const std::shared_ptr &Get() const { typedef std::shared_ptr SharedServicePointer; return std::any_cast( Get(typeid(typename std::decay::type)) ); } /// Tries to look up the specified service /// Type of service that will be looked up /// Shared pointer that will receive the service if found /// True if the specified service was found and retrieved public: template bool TryGet(std::shared_ptr &service) const { typedef typename std::decay::type VanillaServiceType; typedef std::shared_ptr SharedServicePointer; std::any serviceAsAny = TryGet(typeid(VanillaServiceType)); if(serviceAsAny.has_value()) { service = std::any_cast(serviceAsAny); return true; } else { service.reset(); return false; } } /// Looks up the specified service /// Type of service that will be looked up /// /// The specified service as a shared_ptr wrapped in an /// protected: NUCLEX_SUPPORT_API virtual const std::any &Get( const std::type_info &serviceType ) const = 0; /// Tries to look up the specified service /// Type of service that will be looked up /// An Any containing the service, if found, or an empty Any /// /// /// An empty will be returned if the specified service has not /// been activated yet (for a mere container, that means it's not in the container, /// for a factory, it means it has not been constructed yet or its lifetime requires /// that the service instance is not stored). /// /// /// If there is another problem, this method will still throw an exception. /// /// protected: NUCLEX_SUPPORT_API virtual const std::any &TryGet( const std::type_info &serviceType ) const = 0; //private: ServiceProvider(const ServiceProvider &); //private: ServiceProvider &operator =(const ServiceProvider &); }; // ------------------------------------------------------------------------------------------- // }}} // namespace Nuclex::Support::Services #endif // NUCLEX_SUPPORT_SERVICES_SERVICEPROVIDER_H