Dependency Injection Framework (Unity)

Johan Svensson
dotcrossdot
Published in
4 min readSep 9, 2018

One of the first things I noticed when I started programming Unity games is that handling references between object/systems is often awkward and not at all robust.

There are a few built in ways you can do this. The most obvious one is assigning references to objects in the editor. Anyone who has ever worked with Unity in a professional way knows that these references get lost every once in a while due to various reasons. E.g. if you rename the field you set the reference in it will be reset. There are also cases when simply cannot do this in an effective way. E.g. when you want a reference to a shared instance of an object, but the object that needs the reference does needs to be instantiated at runtime.

The other way people solve this is using singletons. There are about 1 million lectures explaining why the singleton pattern is bad, so I’m not gonna go into it very much. However, the reason I don’t like using them (although they are deceptively easy to use) is that you often create very hard to break dependency chains in your classes, which makes them very hard to test. E.g. if you want to create a test scene for a gameobject and test its functionality in isolation you sometimes end up having to add nearly every system in your game to the test scene (since a monobehaviour on it has a long dependency chain of singletons).

To avoid these problems I decided to create a very simple and easy to use dependency injection framework. The entire source code is on my github page:

The way you set it up is very easy. The only thing you have to do is make sure you have an object in your boot scene with a Bootstrapper script, and have it first in your script execution order, like so:

Script execution order.

In your BootStrapper script (which inherits from BaseBootStraper) you register the systems which should be available to your MonoBehaviours.

In the example below I have two classes registered. One with an interface and one without an interface.

To get these references in a MonoBehaviour, either through an interface or by the raw class, you simply add a Dependency attribute to it and call the InjectDependencies method in Awake(), like so:

Thats it. You now have robust yet loose references in your MonoBehaviours. Your dependencies can be interfaces, so you can implement mock classes in order to test your other stuff in isolation. You can also create unit tests for all your systems.

NOTE 1:

The repository link above have two branches which are stable. Master and GameObjectDependency. The master branch handles classes that are simple C# classes (which has been enough for me in my projects). However, when using this professionally in larger teams at Resolution Games I noticed that people wanted to have references to prefab instances instead, so that they could use coroutines and use public fields for config. This is exactly what the GameObjectDependency branch does. The bootstrapper looks a little different. Instead of registering your systems by code you assign them in the editor:

GameObject references

The one rule you have to follow here is that the prefabs you create have to have the exact same name as the MonoBehaviours you want to reference. E.g. the systems in the image above references the following prefabs:

Prefab references.

If you want to use an interface for your scrips. You simply name the prefabs the same as your interface.

NOTE 2:

There is a 3rd branch (DependencyViewer), which is in development and not functional yet. Its a viewer for the dependency graph. The idea is to visualize the objects dependencies, both ingoing and outgoing, as nodes in a tree. I think this would be a cool feature that would help get a better view of the overall architecture of the game. However, as mentioned, its still under development and not near finish. Keep that in mind if you check out the repo.

Thanks for reading! Feel free to mail me if you have any questions.

--

--