winrt::static_lifetime
указывает, что фабрика является одноэлементной, поэтому вам необходимо реализовать экземпляр синглтона как свойство фабрики (теперь одноэлементной).
А именно:
namespace Foo::implementation {
struct Foo : FooT<Foo> {
Foo() {
}
static Foo Singleton() {
auto fooFactory = winrt::make<factory_implementation::Foo>();
return fooFactory->Singleton();
}
};
}
namespace Foo::factory_implementation {
// specifies the factory is a singleton
struct Foo : FooT<Foo, implementation::Foo, winrt::static_lifetime>
{
Foo Singleton() {
slim_lock_guard lock{ m_lock };
if (!m_singleton) {
m_singleton = winrt::make<Foo>();
}
return m_singleton;
}
private:
winrt::slim_mutex m_lock;
Foo m_singleton;
};
}
Так почему же это предпочтительнее по сравнению с чем-то вроде:
static Foo Singleton() {
static auto single = winrt::make<Foo>();
return single;
}
Причина для этого заключается в том, что статика процесса может быть разрушена после RoUninitialize, что приводит к сбою.winrt :: static_lifetime в основном помещает фабрику в CoreApplication.Properties
, которая безопасно инициализируется до того, как процесс выполнит RoUninitialize.Это в основном по той же причине, по которой в прошлом нужно было избегать хранения устаревших COM-объектов в глобалах процессов.