I have a service that needs to be able to handle native assets and attribute types, so I have a core service in my PCL called BaseThemeService which implements interface IThemeService. I need to be able to access some attributes from the core PCL, which is why it implements the IThemeService from the core PCL.
Within each platform project, I have a class ThemeService which implements IDroidThemeService and extends BaseThemeService. I then register the IDroidThemeService singleton in the setup of each project manually.
This works, except that there are now 2 instances of BaseThemeService. 1 that is registered for the IThemeService for the core, and 1 that is registered for the IDroidThemeService for the platform.
To work around this I construct it myself and then register each appropriately:
protected override void InitializeFirstChance()
{
ThemeService themeService = new ThemeService(Mvx.Resolve<IMvxJsonConverter>(), Mvx.Resolve<IMvxResourceLoader>());
Mvx.RegisterSingleton<IDroidThemeService>(themeService);
Mvx.RegisterSingleton<IThemeService>(themeService);
base.InitializeFirstChance();
}
This seems like it should work, but it doesn't since the IMvxJsonConverter and IMvxResourceLoader services have not been registered yet.
I see in the MvvmCross documentation that auto-loading using lazy construction will register a service with all implemented interfaces. Is there a way to use that functionality here to remove the manual registration?
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;
}
This ended up being the ultimate resolution. I know the RegisterAsLazySingleton looks to solve this problem automatically, so I'll update again if I find a way to implement this that is slightly cleaner.
You can register a factory for the singleton which can produce a singleton manually and return that whenever anyone wants to call it. 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();
}
Depending on your situation, it may be appropriate for the field and method to be static.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With