Service Locator in Unity: Simplifying Dependency Management

Utku Akyıldız
3 min readMar 8, 2023

--

Managing dependencies in game development can be challenging, especially as your project grows in complexity. To keep your code maintainable and scalable, it’s essential to decouple it and make it more modular. One way to achieve this is through inversion of control.

In this post, we’ll explore the Service Locator pattern, my preferred type of inversion of control in Unity. We’ll discuss the advantages and disadvantages of using this pattern and explain why it’s my preferred approach. Additionally, I’ll provide practical examples of how to implement and use it in your Unity projects.

By the end of this post, you’ll have a solid understanding of the Service Locator pattern and how it can simplify the management of dependencies in your Unity project. Let’s get started!

1. Inversion of Control

Inversion of Control (IoC) promotes loose coupling between components by reversing the traditional flow of control in an application. Instead of components controlling the instantiation and management of their dependencies, dependencies are injected by an external entity.

There are two main types of IoC: Dependency Injection (DI) and Service Locator. While both patterns aim to achieve loose coupling and modular design, they differ in how dependencies are resolved.

2. Dependency Injection

Dependency Injection (DI) is a design pattern that allows for the creation of dependent objects outside of a class and provides those objects to a class. This moves the creation and binding of dependent objects outside of the class that depends on them. A common type of DI is Constructor Injection. Lets look at an example:

public class Foo {
private Bar bar;

public Foo(Bar bar) {
this.bar = bar;
}
}

As you can see in this example, you don’t need to look inside the class to know its dependencies. They are explicitly shown in the constructor.

3. Service Locator

The Service Locator pattern centralizes dependency management in your application by providing a middleman between components and services. This reduces coupling between different parts of your application and makes it easier to swap out implementations of services or add new services as needed. Here’s an example:

public class Foo {
private Bar bar;

public Foo() {
this.bar = ServiceLocator.Get<Bar>();
}
}

4. Service Locator is an Anti-pattern

The point of DI is to ensure that dependencies are clearly defined and visible. Once you hide those dependencies by not making them explicit parameters in a constructor, you’re not fully implementing IoC because the class is still responsible for creating its own dependencies. It just uses the Service Locator to do it. With DI, the class is given its dependencies, it neither knows, nor cares where they come from.

In the Service Locator example above, you need to check the class to know its dependencies but with DI, you don’t have to do that.

5. So why do I still prefer Service Locator over Dependency Injection in Unity?

This is mostly due to personal experience and preference, and the keyword here is “in Unity”. Implementing DI in Unity can be complex, so developing my own DI system is not worth the effort.

What about frameworks? DI frameworks in Unity caused me a lot of issues. I spent more time working on a DI system than the DI system working for me. Additionally, many of these frameworks are not actively maintained, with some having not been updated in 2–3 years. Even if an up-to-date DI framework existed, I think it’s overkill to add a whole framework just for DI in Unity.

So, even though Service Locator is not a perfect IoC, it gets pretty close and worked great for me in Unity.

6. Implementing Service Locator in Unity

7. Using Service Locator in Unity

Registering Services
Example Game Object Registering Services

Once a service is registered, you can retrieve it using the following method:

GameManager gameManager = ServiceLocator.Get<GameManager>();

8. Conclusion

In game development, it’s important to manage dependencies to keep code organized and adaptable. While Dependency Injection is typically preferred, it can be complicated to use in Unity. Service Locator is a useful alternative that simplifies dependency management in your game. With the examples provided, you can effectively implement and use Service Locator in your Unity projects.

9. Whats next?

In my next blog post, I’ll show you how to use multi-scene workflow to better organize your Unity project and make the most of the Service Locator.

--

--