Skip to main content

Service Location in Umbraco 9

I should probably start this post with a caveat saying, "don't do this... unless you really, really have to!"

With Umbraco 9, built on .NET 5, we have support for the dependency injection design pattern, and where possible, the recommedation is to use that, to promote testability and other best practices.

Within the Umbraco CMS source code though, and also in the add-on products Forms and Deploy, we have found it necessary to use service location in a couple of instances. Primarily, to avoid breaking changes. For example, when a public class requires a new dependency, we don't just add it to the constructor as that would potentially break integrations that are already using it. Instead we obsolete the existing constructor, create a new one with the additional parameter, and have the original constructor delegate to the new one - using service location to provide the parameter for the added dependency.

In code it looks like this:

To use, you need to be referencing Umbraco CMS 9.0.1 or higher (in 9.0.0 the StaticServiceLocator class was internal). And reference these two namespaces:

The source for the StaticServiceProvider class is here, where you can also read the comments discussing it's use cases. To reiterate, for most Umbraco projects there should be no need to use this. Instead dependency injection should be used, either directly for the component you need or via one of the "accessor" classes like IUmbracoContextAccessor. But if building a package, and similarly wanting to avoid breaking changes, it may be a useful technique to consider.