2015-03-02 11 views
6

Mam usługę, która musi być w stanie obsłużyć natywne zasoby i typy atrybutów, więc mam podstawową usługę w moim PCL o nazwie BaseThemeService, która implementuje interfejs IThemeService. Muszę mieć dostęp do niektórych atrybutów z rdzennego PCL, dlatego implementuje on IThemeService z podstawowego PCL.Rejestracja pojedynczego singleton dla wielu interfejsów w IOC

W ramach każdego projektu platformy mam klasę ThemeService, która implementuje IDroidThemeService i rozszerza BaseThemeService. Następnie rejestruję singleton IDroidThemeService w konfiguracji każdego projektu ręcznie.

Działa to, z tym że istnieją teraz 2 wystąpienia BaseThemeService. 1, który jest zarejestrowany dla IThemeService dla rdzenia i 1, który jest zarejestrowany dla platformy IDroidThemeService.

Aby obejść ten skonstruować go samodzielnie, a następnie zarejestrować każdy odpowiednio:

protected override void InitializeFirstChance() 
{ 
    ThemeService themeService = new ThemeService(Mvx.Resolve<IMvxJsonConverter>(), Mvx.Resolve<IMvxResourceLoader>()); 
    Mvx.RegisterSingleton<IDroidThemeService>(themeService); 
    Mvx.RegisterSingleton<IThemeService>(themeService); 

    base.InitializeFirstChance(); 
} 

Wydaje się, że powinna działać, ale tak nie jest, ponieważ usługi IMvxJsonConverter i IMvxResourceLoader nie zostały jeszcze zarejestrowane.

Widzę w dokumentacji MvvmCross, że automatyczne ładowanie z wykorzystaniem leniwej konstrukcji spowoduje zarejestrowanie usługi ze wszystkimi zaimplementowanymi interfejsami. Czy istnieje sposób na wykorzystanie tej funkcji w celu usunięcia ręcznej rejestracji?


Odpowiedź

protected override void InitializeFirstChance() 
{ 
    Mvx.RegisterSingleton<IDroidThemeService>(GetThemeService); 
    Mvx.RegisterSingleton<IThemeService>(GetThemeService); 

    base.InitializeFirstChance(); 
} 

private DroidThemeService DroidSingletonService = null; 
private DroidThemeService GetThemeService() 
{ 
    if (DroidSingletonService == null) 
    { 
     DroidSingletonService = Mvx.IocConstruct<DroidThemeService>(); 
    } 
    return DroidSingletonService; 
} 

To okazało się być ostatecznym rozdzielczości. Wiem, że RegisterAsLazySingleton szuka rozwiązania tego problemu automatycznie, więc zaktualizuję go ponownie, jeśli znajdę sposób na wdrożenie tego, który jest nieco bardziej przejrzysty.

Odpowiedz

4

Możesz zarejestrować fabrykę dla singleton, która może utworzyć singleton ręcznie i zwrócić, gdy ktoś chce to nazwać. See the docs for Lazy Singleton Registration

ThemeService singletonService = null; 
private ThemeService GetThemeService() 
{ 
    if (singletonService == null) 
    { 
     singletonService = new ThemeService(Mvx.Resolve<IMvxJsonConverter>(), Mvx.Resolve<IMvxResourceLoader>()); 
    } 
    return singletonService; 
} 

protected override void InitializeFirstChance() 
{ 
    Mvx.RegisterSingleton<IDroidThemeService>(GetThemeService); 
    Mvx.RegisterSingleton<IThemeService>(GetThemeService); 

    base.InitializeFirstChance(); 
} 

W zależności od sytuacji, może być właściwe dla zakresu i sposobu, aby być statyczna.

+0

Rozwiązuje to problem rozwiązywania zależności przed ich zarejestrowaniem. – BayssMekanique

+2

BTW: możesz użyć Mvx.IoCConstruct (). Wywołuje konstruktora i automatycznie rozwiązuje parametry zamiast ręcznie wywoływać Resolve () dla każdego. – Kiliman

+1

Jest pomocnik 'MvxLazySingletonCreator' w CrossCore, jeśli to pomaga - zobacz kod w https://github.com/MvvmCross/MvvmCross/blob/3.5/CrossCore/Cirrious.CrossCore/IoC/MvxTypeExtensions.cs#L186 – Stuart

Powiązane problemy