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