Неинициализированный сервис в другой DLL с использованием шаблона поиска сервисов - PullRequest
0 голосов
/ 31 декабря 2018

Я пытаюсь применить шаблон локатора службы к моей существующей базе кода, которая состоит из нескольких модулей (dylibs) и тестового приложения.Я использую сервисные локаторы, которые в основном выглядят так:

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 ...).Однако моя кодовая база состоит из большего количества сервисных локаторов, которые в основном похожи на реализацию выше, с другим типом сервиса.Поэтому я решил создать общий класс ServiceLocator, настроенный с параметром Service, чтобы предотвратить повторное написание одного и того же кода.Мой общий класс 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;
};

Однако после этого изменения мой сервис доступен только модулю, который его создал (модуль Б).Это происходит только в macOS, но работает в MSVC.

Чего мне не хватает?

...