使用服务定位器模式在其他DLL中进行未初始化的服务

时间:2018-12-31 14:37:40

标签: c++ macos dylib service-locator dynamic-library

我正在尝试将服务定位器模式应用于现有的代码库,该代码库由几个模块(dylib)和测试应用程序组成。我一直在使用基本上如下所示的服务定位器:

class FILESYSTEM_API FileSystemServiceLocator
{
public:
    static void Provide(std::unique_ptr<IFileSystemService> service)
    {
        mService = std::move(service);
    }

    static IFileSystemService& Service()
    {
        return *mService;
    }

    static bool Available()
    {
        return mService != nullptr;
    }

private:
    static std::unique_ptr<IFileSystemService> mService;
};

然后在实现文件IFileSystemService中的某个地方,我声明静态成员std::shared_ptr<IFileSystemService> FileSystemServiceLocator::mService = nullptr;。现在,如果我在模块A(dylib)中创建服务并将其传递给Provide方法,则可以通过任何其他模块(B,C,D ...)中的服务定位器访问该服务。但是,我的代码库包含更多的服务定位器,基本上与上面的实现类似,具有不同的服务类型。因此,我决定创建以Service参数为模板的通用ServiceLocator类,以防止一次又一次地编写相同的代码。我的通用Service Locator类如下所示:

template<class T>
class ServiceLocatorBase
{
public:
    static void Provide(std::unique_ptr<T> service)
    {
        Storage() = std::move(service);
    }

    static T& Service()
    {            
        return *Storage();
    }

    static bool Available()
    {
        return Storage() != nullptr;
    }

private:
    static std::unique_ptr<T>& Storage()
    {
        static std::unique_ptr<T> service;
        return service;
    }
};

我的FileSystemServiceLocator看起来像这样:

class FileSystemServiceLocator : public Core::ServiceLocatorBase<IFileSystemService, FileSystemServiceLocator>
{
public:
    FileSystemServiceLocator() = default;
};

但是,此更改之后,我的服务仅对创建它的模块(模块B)可用。这仅在macOS上发生,但在MSVC上有效。

我想念什么?

0 个答案:

没有答案