Search code examples
c++-winrt

How do i get the Instance of the class when i use winrt::static_lifetime?


I switched from C++/CX to C++/winrt not long ago and I'm currently stuck because I want to create a singleton winrt-class. I read about winrt::static_lifetime (https://learn.microsoft.com/en-us/uwp/cpp-ref-for-winrt/static-lifetime), but they don't provide any code example on how to use it. So my Question is how do I get the Instance of the class with this?

Thanks for the help in advance.


Solution

  • winrt::static_lifetime specifies that the factory is a singleton so you basically need to implement the singleton instance as a property of the (now singleton) factory.

    Namely:

    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;
        };
    }
    

    So why is this preferred at all in comparison to something like:

    static Foo Singleton() {
        static auto single = winrt::make<Foo>();
        return single;
    }
    

    The reason to do this is because process statics may be destroyed after RoUninitialize resulting in a crash. winrt::static_lifetime basically puts the factory into CoreApplication.Properties which is uninitialized safely before the process does RoUninitialize. It's basically for the same reason why storing legacy COM objects into process globals needed to be avoided in the past.