[MVVMbasics] Dependency Injection into Viewmodels and Services

All blog posts with a title that starts with [MVVMbasics] are related to the MVVMbasics framework. If you are only interested in my regular blog posts and not in MVVMbasics, ignore these. To list all articles covering MVVMbasics, go to http://mvvmbasics.mobilemotion.eu/documentation!

One of the core features of the MVVMbasics framework is the global ServiceLocator. This object holds references to all services preent within the project, but instantiates them not until they are used for the first time. In older versions of the framework (until 2.0), the global ServiceLocator instance would automatically be injected into each Viewmodel that inherits from BaseViewmodel and could be accessed through the Viewmodel’s ServiceLocator property. From version 2.1 on, the ServiceLocator property in each Viewmodel is considered deprecated (which means it still works and it’s therefore not necessary to refactor existing projects instantly, but it might be removed from the framework in future versions).

The new way of injecting the global ServiceLocator instance into Viewmodels and accessing Services from within Viewmodels is to provide a Viewmodel constructor that accepts one parameter of type ServiceLocator. Every Viewmodel that derives from BaseViewmodel will be instantiated using this constructor, if available. The global ServiceLocator instance can be stored in a private field within this construtor, which allows access to Services from everywhere within the Viewmodel:

public class MyViewmodel : BaseViewmodel
{
	private readonly ServiceLocator _serviceLocator;
	
	public MyViewmodel(ServiceLocator serviceLocator)
	{
		_serviceLocator = serviceLocator;
	}
	
	private void SomeMethod()
	{
		_serviceLocator.Retrieve<ISomeService>().SomeServiceMethod();
	}
}

Compared to the old approach of auto-injection, this architecture brings about two advantages: The OnServiceLocatorAvailable method is not necessary anymore, and the ServiceLocator instance can also be injected into other Services, discussed in the following two sections:

Accessing Services from within a Viewmodel’s constructor:

In older versions of the MVVMbasics framework, the automatic injection of the global ServiceLocator instance happened shortly after the Viewmodel’s constructor method. This means that it was impossible to access Service methods from within a Viewmodel’s constructor – trying to do so would result in a NullReferenceException since ServiceLocator was still null within the constructor. Therefore the OnServiceLocatorAvailable method was introduced that could be overwritten to be informed as soon as the ServiceLocator instance was actually available. Since in version 2.1, the ServiceLocator instance is passed directly to the constructor as parameter, this method is not necessary any more and will also be marked deprecated.

Using the ServiceLocator within Service instaces:

In some cases it might be useful to access Service methods not only from within Viewmodels but also in other Services. Therefore it’s now possible to inject the global ServiceLocator instance into Service classes the same way as into Viewmodels:

[MvvmService]
public class MyService : IMyService
{
	private readonly ServiceLocator _serviceLocator;
	
	public MyService(ServiceLocator serviceLocator)
	{
		_serviceLocator = serviceLocator;
	}
	
	private void SomeServiceMethod()
	{
		_serviceLocator.Retrieve<ISomeOtherService>().SomeOtherServiceMethod();
	}
}