I am currently trying to integrate dependency injection into my xamarin forms cross platform mobile app using the Microsoft.Extensions.DependencyInjection library. I was able to register my services and viewmodels in my shared project, but I am unsure of how to register services that are implemented in platform specific projects. For example, I have an interface (IAuthenticationService) which is implemented through platform specific code, so it has implementations in my Android and iOS projects, but I'm not sure how to register that with my container so that the right implementation will be used based on the current running platform. This is how I set up my DI container in my startup class within my shared project:
public static class Startup
{
public static IServiceProvider ServiceProvider { get; set; }
public static IServiceProvider Init()
{
// Initialize all viewmodels and services with DI container
var serviceProvider = new ServiceCollection().ConfigureServices().ConfigureViewModels().BuildServiceProvider();
ServiceProvider = serviceProvider;
return serviceProvider;
}
}
public static class DependencyInjectionContainer
{
public static IServiceCollection ConfigureServices(this IServiceCollection InServices)
{
//InServices.AddSingleton<IAuthenticationService>();
InServices.AddSingleton<ISystemLayoutModel, SystemLayoutModel>();
return InServices;
}
public static IServiceCollection ConfigureViewModels(this IServiceCollection InServices)
{
InServices.AddTransient<LoginViewModel>();
InServices.AddTransient<StartViewModel>();
InServices.AddTransient<RegistrationViewModel>();
//All other viewmodels
return InServices;
}
}
And I call Init() in my App.xaml.cs to initialize the container with all the services and viewmodels:
public partial class App : Application
{
public App()
{
InitializeComponent();
Startup.Init();
MainPage = new AppShell();
}
}
And everytime I want to inject a dependency into my viewmodel, I do something like this in the view code behind
IStartViewModel _vM;
public StartPage()
{
InitializeComponent();
_vM = Startup.ServiceProvider.GetService<StartViewModel>();
BindingContext = _vM;
}
And the following viewmodel would look something like this:
class StartViewModel : ViewModelBase, IStartViewModel
{
protected ISystemLayoutModel _LayoutModel;
public StartViewModel(ISystemLayoutModel InSystemLayoutModel)
{
_LayoutModel = InSystemLayoutModel;
LoadItemsForStart();
if (_LayoutModel.SystemStartLayoutScreen.StartScreenTypes.Count < 1)
{
// Shutdown the application if it is not startup properly
Application.Current.Quit();
}
}
// More code
}