Simple service locator for your Unity project

Dino Fejzagić
medialesson
Published in
4 min readJan 22, 2020

There are many great tutorials on Unity out there on the internet for you to learn from. Most of them target Unity beginners though or keep their samples very simple and do not pay attention to more advanced coding techniques. In this article we’ll learn how we can write our very own simple service locator in Unity and use it to optimize our code architecture and maintainability.

Very often you’ll find awesome coding tutorials on Unity which will include a combination of these “pitfalls” for simplicity:

  • Only public fields in scripts
  • Make everything a Singleton
  • Non performance-optimized code
  • Synchronous scene loading
  • Only MonoBehaviours

We could go on here. Don’t get me wrong, nothing wrong about it. They still carry the message and instructions they intend to teach their audience. Let’s take a look at how we can implement a simple Service Locator pattern to improve on some of these aspects.

Creating a new Unity project

You can go ahead and create a new Unity project to work with or implement it right into your existing project, as you like. I am using Unity 2019.3.0f5 here.

  • Open Unity Hub
  • Create a new project using whichever template you like
  • In your Assets folder create a new folder and name it ServiceLocator, we’ll put all the code in here

Implementing the service locator

In the first step let’s create a service interface for our service locator to work with. Inside yourAssets/ServiceLocator folder create a new script file IGameService.cs:

As you can see we leave it empty for now. We want to keep this sample really simple. Once you we got everything in place, you can use this interface to define what your services have in common and should look like and which APIs they provide.

Next we actually already get to implement the service locator. Again in Assets/ServiceLocator create a new script file ServiceLocator.cs:

A few more things going on here. Let’s step through:

  • private ServiceLocator() {} we make default constructor private to avoid misuse of the service locator by creating new instances of it randomly.
  • Dictionary<string, IGameService> services will hold all currently registered services using their type name as the key to retrieve them.
  • public static ServiceLocator Current { get; private set; } a static property which will hold the currently active service locator instance. This should be the only Singleton in your application basically from now on.
  • Initialize() will initialize the active service locator with a new instance.
  • public T Get<T>() where T : IGameService is used to get a service instance from the service locator. We are restricting the generic type T to types implementing our IGameService interface.
  • public void Register<T>(T service) where T : IGameService is used to register a service instance with our locator. It will then be available using Get<T> .
  • public void Unregister<T>() where T : IGameService for completeness we provide a way here to unregister a service of a given type from the locator.

And that’s it regarding the locator itself! Did I mention we want to keep this locator simple? Doesn’t get any simpler I think. Worth nothing here is that this service locator will only allow one instance of a service of a given type. Which should do the trick on most cases. You can modify it to support multiple instances of a type easily.

Bootstrapping the service locator

Now that we have our locator implemented let’s see how we can initialize it when the application starts.

In Assets/ServiceLocator create a new script file Bootstrapper.cs:

Ok. Let’s see what’s going on here. I am assuming for this bootstrapper script that you have some sort of “Base Scene” in your Uniy project. This should be the scene at index 0 of your overall scenes. Use it to get your application ready and initialize everything other scenes may need to work with.

[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)] using this attribute we tell Unity to run the static method Initialize() once the base scene has fully loaded. Inside Intialize() we create the service locator instance and then proceed to register all our game services with it. Once that is done, we can load our main scene which will contain appilcation content using those services eventually. You can extend this bootstrapper as needed.

What we learned and gained

In this short sample we learned how to implement our very own service locator and use it in our Unity project. But what did we gain?

  • You will find that it’s much easier for you now to separate business logic code from visualization code. Your game services can take care of handling data and such, while you’ll be creating MonoBehaviours to visualize it and use it.
  • This service locator is a good starting point to think about how you can implement Dependency Injection in your project next.
  • You can now easily write Unit Tests out of Unity for your services since they are not MonoBehvaiours anymore.

About reinventing the wheel

Of course you don’t have to reinvent the wheel here. There is existing service locator implementations for Unity out there. If you like the idea, I can recommend taking a look at

XRTK and MRTK for two examples of existing implementations. Both provide a very good starting point for you and ways to implement your own services and register them with their service locator.

--

--

Dino Fejzagić
medialesson

Senior XR Engineer and CTO CodeEffect GmbH. My topics include Unity, AR/VR/XR, Game Dev, Software Engineering