IoC Container for Unity3D – part 2

By Sebastiano Mandalà

In my previous article I briefly introduced the problems related to inject dependencies using Unity 3D Framework.
I did not give an in depth explanation because only who understood the problem on its own can really understand why to look for a solution.

Before to discuss the example I built on purpose to show the features of the framework, I want to share with you my experience with the IoC containers I used before to write mine.

As pure game developer, IoC container was a weird concept to me, although I probably used Inversion of Control without knowing what it was and what it was called.

My experience with other IoC containers

When I was introduced to the concept of Dependency Injection and all the problems related to it, the IoC container was among the most used solutions.
That’s why, when I shifted from traditional C++ programming to actionscript game development, I started to use Robotlegs. Robotlegs is an actionscript IoC Container.

After I used it for a couple of small personal projects, I decided to abandon it. This is because eventually I ended up convincing myself that manual Dependency Injection through setter and getters was a better practice.

However after some time, when I moved to C#, I started to experiment with Ninject and discuss the practices with its author.
As result of these discussions I realized that I was not appreciating the use of an IoC container because I did not understand its principles.

Composition Root

The most important concept to understand is the Composition Root. The Composition Root often coincide with the application entry point, but in practice it is the place where the IoC container must be initialized before everything else starts to use it. Since an application could use more IoC containers, it could have more composition roots as well.

Object Graph

When your classes design is created (without using singletons), your classes start to form a graph of dependencies. Let’s say that there is a class A and a class B, then there is a class C that uses A and a class D that uses B and C. This waterfall of dependencies is called Object Graph.

How to use an IoC Container

Now, as long as the objects do not need to be created after the application has been initialized, all the dependencies can be solved right at the begin of your application, within the Composition Root context.

This is very important to understand, in fact my first error was to inject the container itself inside the objects to be able to fill their dependencies that I used to create explicitly using the new keyword.

The rule instead is that the container should be explicitly used only in the Composition Root. Exceptions, most of the time, mean that there is something wrong in the design.

In our example the Composition Root looks like this:

container will not be used in any other part of the example, except for the factories. Factory is a special case and I will explain it later.

What is happening? Inside the SetupContainer method, we are not simply registering the classes into the container, but we are actually setting up the flow of our dependencies. Dependencies that are solved lazily (that means only when requested) through the metatag [IoC.Inject].

In our case, the application flow starts from this method:

After the MonsterSpawner is built, it will have the dependency IMonsterFactory injected because it has been declared like this:

[IoC.Inject] public IMonsterFactory monsterFactory  { set; private get; }

and because IMonsterFactory has been previously registered (and bound to a valid implementation) inside the container. In this specific case is simple to understand how the MonsterSpawner dependencies have been explicitly injected by the container. However the container will not be explicitly used anywhere else, so the other dependencies will be injected thanks to the Object Graph.

This means that monsterFactory on its turn will have (automatically) injected the dependencies:

[IoC.Inject] public IoC.IMonoBehaviourFactory monoBehaviourFactory { set; private get; }
[IoC.Inject] public IMonsterSystem                   monsterSystem             { set; private get; }

If monsterSystem had some dependencies too, they would have been injected as well and so on….

In a complicated project scenario this system eventually will give the impression that the [IoC.Inject] metatag becomes a sort of magic keyword that would solve all our dependencies.

Of course there is nothing of magic and, differently than Singleton containers, our dependencies will be correctly injected ONLY if they are part of the Object Graph.

The Object Graph itself is the main difference between the use of an IoC container and a Singleton container. The dependencies are not scattered without any condition among the classes, but they must follow the Object Graph flow.

If, using Singletons and Singleton containers, your code starts to feel like a game of Jinga, than it is probably the time to start to look at the Inversion Of Control solution.

IoC container and the keyword new

it is called Inversion Of Control because the principle is that the code should not use the keyword new at all. The control (of the creation of the objects) is not anymore on the user, but on the framework that will create and inject the objects for him.

The most powerful benefit behind this concept is that the code will not rely on the implementation of the classes anymore, but always on their abstractions (if interfaces are used).

Relying on the abstraction of the classes gives many benefits that can be fully understood when practices like refactoring and unit testing are heavily used. Regardless these concepts, coders should anyway use interfaces to create clean and well designed code.

all that said, one could ask: if I should not use new, how is it possible to create objects dynamically, while the application executes, like for example spawning objects in my world?

My answer is to use Factories. Factories, in my design, can use the container to inject the object that they create.

your class could have something like:

Beside, if you wonder why your class should not be able to create objects on its own, remember that this is not over engineering, this is separation of concerns.

Creating bullets and handle them are two different responsibilities and respecting the Interface Segregation Principle (part of the SOLID principles that should be your coding commandments) is one of the most important design rule in order to not have humongous and cluttered classes.

IoC container and Unity

The use of an IoC container, similar to the one I am showing in this article, will help to shift the coding paradigm from an intensive use of Monobehaviour to the use of normal classes that implement interfaces.

However Monobehaviour, on its pure form, is a totally useful tool and its use must be encouraged when appropriate. Still our Monobehaviours need dependencies that must be injected.
Now, if the Monobehaviours are created dynamically through factory, as it should happen most of the times, then the dependencies will be solved through the Object Graph.
However, if monobehaviour are created implicitly, their dependencies cannot be solved within the Composition Root because of the nature of the Unity Framework.

For instance, in my example, the turrets are not created dynamically (they could have been though), as well as the monsters counter shown on the top left corner.

There is no proper way to find a workaround to this limitation. My personal solution has been to create an extension method, called Inject, that can be used with Monobehaviour scripts.

the Monobehavior classes, created implicitly by the framework, that need dependency injected, use the extension in this way:

After this function is called, all the dependencies will be injected. There are conditions though:

  • The GameObject must be in a hierarchy where one of the parent GameObject has one valid UnityContext monobehaviour set.
  • The UnityContext must be initialized before the extension method is used. This can be achieved using Start or changing the Script Execution Order.

IoC Container and MVC (MVP, MVVM)

IoC container become also very useful when patterns like Model View Controller (or the more recent Model, View, Presenter and Model, View, ViewModel) are used.
Theoretically the triad should not be known outside the triad itself, since the way to communicate outside is to use services or command injected. The explanation of this case is not part of the scope of this article, so maybe I could write about it in another one.

However it is interesting to highlight how I also use these patterns to uncouple the data that we want to be edited through the editor and the logic that must use this data.

Usually what happens is that, just because we want to let the designer edit some public variables of a class, it becomes a Monobehaviour without any other reason. The way to get around this problem is to create a Monobehaviour that just handles this data and so become a sort of Model. This is what happens in our example with the PathModel class.

While you can change the way I exploited the idea in several ways, the main concept is that the monobehaviour is totally uncoupled from the logic (pathController) and it could even be destroyed since it is not needed for our purposes anymore.

IoC Container and Unit Tests

Often IoC container is associated to Unit Tests. However there is not any direct link between the two practices. In fact very often Unit Tests do not use IoC containers at all.
Instead the point is that the use of an IoC container, against the use of static classes, will help the coder to write Unit Test friendly classes.

In fact Unit tests must test ONLY the code of the testing class and NEVER its dependencies. Using Dependency Injection will make very simple to create dumb mockup to inject valid dependencies that cannot ever break or affect the tests of the main class itself. This can happen thanks to the use of interfaces, where the mockups become just one different (often empty) implementations used for the scope of the tests only.

Unit testing is also outside the scope of this article and maybe I will write one on purpose in future.

Conclusion

before to conclude, I want to quote two answers I found on StackOverflow that could help to solve some other doubts:

from http://stackoverflow.com/a/2551161

The important thing to realize here is that you can (and should) write your code in a DI-friendly, but container-agnostic manner.

This means that you should always push the composition of dependencies to a point where you can’t possibly defer it any longer. This is called the Composition Root and is often placed in near the application’s entry point.

If you design your application in this way, your choice of DI Container (or no DI Container) revolves around a single place in your application, and you can quickly change strategy.

You can choose to use Poor Man’s DI if you only have a few dependencies, or you can choose to use a full-blown DI Container. Used in this fashion, you will have no dependency on any particular DI Container, so the choice becomes less crucial in terms of maintainability.

A DI Container helps you manage complextity, including object lifetime. Used like described here, it doesn’t do anything you couldn’t write in hand, but it does it better and more succinctly. As such, my threshold for when to start using a DI Container would be pretty low.

I would start using a DI Container once I get past a few dependencies. Most of them are pretty easy to get started with anyway.

and from http://stackoverflow.com/a/2066827

Pure encapsulation is an ideal that can never be achieved. If all dependencies were hidden then you wouldn’t have the need for DI at all. Think about it this way, if you truly have private values that can be internalized within the object, say for instance the integer value of the speed of a car object, then you have no external dependency and no need to invert or inject that dependency. These sorts of internal state values that are operated on purely by private functions are what you want to encapsulate always.

But if you’re building a car that wants a certain kind of engine object then you have an external dependency. You can either instantiate that engine — for instance new GMOverHeadCamEngine() — internally within the car object’s constructor, preserving encapsulation but creating a much more insidious coupling to a concrete class GMOverHeadCamEngine, or you can inject it, allowing your Car object to operate agnostically (and much more robustly) on for example an interface IEngine without the concrete dependency. Whether you use an IOC container or simple DI to achieve this is not the point — the point is that you’ve got a Car that can use many kinds of engines without being coupled to any of them, thus making your codebase more flexible and less prone to side effects.

DI is not a violation of encapsulation, it is a way of minimizing the coupling when encapsulation is necessarily broken as a matter of course within virtually every OOP project. Injecting a dependency into an interface externally minimizes coupling side effects and allows your classes to remain agnostic about implementation.

The Example

The framework and the example can now be found on GitHub (I use bitbucket only for temporary or personal projects) at: https://github.com/sebas77/Lightweight-IoC-Container-for-Unity3D. You are very welcome to modify it and share your improvements to the other users.

Note: you can add more turrets if you want using the Editor, thanks to the IoC everything will work without touching code.

41 Comments Leave a comment

  1. Super-interesting again. I’m still super-busy right now, but I can’t wait to try this on a simple game.

  2. Thanks for the article, I have been thinking about how to apply DI to Unity as well. Looking forward to more in the series.

  3. Hi and thank you for the comment. I am not planning to write other articles on the topic (I have so many other things I want to talk about), however if you have some other feedbacks or something else you want to discuss, let me know.

    • Since you mentioned you’re done with this topic, and if we had “something else to discuss”, I would vote for an article about using Entity Systems in Unity.

  4. Ah, well…Unity adopts already the Entity Framework concept …however in my example I showed how a “System” can be introduced (the monsterSystem) which can act as mediator on all the monsters.

  5. Hey, very nice articles, that’s exactly what I was looking for, since I come from Flash, huge social games, and I always used Robotlegs or Parsley. Switching to Unity was good but at the same time frustrating to see how “primitive” the software architecture of most of the games out there are.

    What is you opinion about this IoC framework?
    http://www.ninject.org/

    I came across this framework from the post on this blog:
    http://outlinegames.com/2012/08/29/on-testability/

    I’d like to hear your thoughts on that, you can send me an e-mail if possible, thanks a lot!

  6. Hey. I was very interested in this but I get the same error as Rafael.“The referenced script on this Behaviour is missing!”

    I use Unity 3.5. As I understand it, I don’t see any scripts in the unitypackage what so ever. Isn’t that the real issue?

    Would be really cool to see your example!
    Kind regardsm,
    Niklas

  7. Hey, I began using your framework, and it’s been making my life much easier. But I’m having problems when I load a new Scene. The “game context” where I setup the container and make all bindings is on the “MainScene”, and it gets destroyed when I switch to another scene. Even using DontDestroyOnLoad doesn’t help.

    How do you setup your project if you need to load/unload scenes? Thank you!

    • Good question. I honestly do not like the idea to keep the container alive through the levels, it can easily create memory leaks. In our (big) project the idea is pretty simple, the container is setup in one .cs file that is linked to one gameobject present in each level. That means that we actually want the container to be destroyed and recreated everytime. This is ok for us, because our data is not meant to be permanent among the levels, is this a problem for you? Let’s discuss it, it is possible that I did not think through it.

      • I’m working at Wooga with social/mobile games, and from experience it’s fundamental that we have access to the container at anytime, we usually have persistent information across levels. And regarding memory leak, I think it will not be a problem, since there is only “models” and “controllers” stored in the container, low memory usage.

        All the heavy “view” related stuff that really consumes memory (like textures, sprite-sheets, etc) can be destroyed whenever you load/unload scenes.

        I managed to make it work now, I just made the container a static class. In every scene I have a MonoBehaviour object called “GameInit” that will initialize the container, make all the bindings, etc. If it has been already initialized, I skip it.

        This way I can test the game from anywhere, and when I test from the main menu, the other scenes will not initialize twice.

        Anyway, I’m still only prototyping a game, so for “production code” I might change it. Hope that helps! And looking forward to more stuff from you.

        • Thanks for the feedback. Using the container as a static class defeats the purpose of the inversion of control container design itself, because it practically becomes a service locator.
          This is what I suggest you to do:

          Assuming that you do not have much data to be persistent and this data is unique (like the user inventory, energy and stuff like that), use a class like this to bind in the container:

          class UserInventoryController
          {
          static UserInventoryModel userInventoryModel;
          }

          your container is not static, your UserInventoryController is not static and can be injected, but the data inside is static and permanent. Your problem should be solved in this way.

          • Sorry, I made the GameContext static, not the Container. Here is the code I’m using for the context:

            using IoC;
            using UnityEngine;

            internal class AppRoot : IContextRoot
            {
            public IContainer container { get; private set; }

            public void Setup()
            {
            container = new IoC.UnityContainer();
            container.Bind().AsSingle();
            container.Bind().AsSingle();
            container.Bind().AsSingle();
            }
            }

            static public class StaticGameContext
            {
            public static bool GameAlreadyInitialized;
            private static AppRoot _applicationRoot;

            static public void Init()
            {
            if (GameAlreadyInitialized)
            {
            D.error(“Game Context Already Initialized!”);
            return;
            }

            _applicationRoot = new AppRoot();
            _applicationRoot.Setup();
            GameAlreadyInitialized = true;
            }

            static public void InjectMonoBehaviour(MonoBehaviour script)
            {
            DesignByContract.Check.Require(_applicationRoot != null && _applicationRoot.container != null,
            “Container not initialized correctly, possible script execution order problem”);

            _applicationRoot.container.Inject(script);
            }
            }

            And I changed the MonoInjection.cs to this:

            using UnityEngine;

            public static class MonoInjection
            {
            public static void Inject(this MonoBehaviour script)
            {
            StaticGameContext.InjectMonoBehaviour(script);
            }
            }

          • And in the the “GameInit : Monobehaviour” I do this:

            if (StaticGameContext.GameAlreadyInitialized)
            {
            Destroy(this);
            return;
            }

            StaticGameContext.Init();

        • At the end of the day use what suits you best, but I suggest you to try my solution as well and see if you like it (static Model for permanent data)

  8. Good Article,
    Now I know why you write your own IOC,

    I’m trying to learn to write better code as mine is what’s the word rubbish, so may give your IOC a test drive. Still trying to get my head around Agile and Solid principles so its nice to have come across your articles.

    I’m also looking to use BDD which i’m thinking may be a good fit for games have you tried user stories with Unity3d

  9. Hi, i am starting my project to the faculty and i got interested in your work. Did you try to use spring.net framework? Is it possible to use XML to initilize objects.
    I am interested to in the features of permanent data thought scenes too.

    • Hello, thanks for your comment. Most of the c# IoC libraries do not work in Unity3D. I know about the XML feature, but it was not something important for me to implement. However the code is opensource, maybe someone could improve it in future :)

  10. Thanks for your quick reply and good luck for your project

  11. Hi! I managed to use your framework in my project in a simple and fairly intuitive maner. I just could not put the container persistent through the levels. This feature interested me a lot since i am initializing a set of objects and configuration managers through XML and i wished they were available throughout the various levels. Maybe the problem is in the design of my application due to my lack of experience.
    My initial approach used a singleton that persisted through various levels, but your solution is much more cleaver and clean however the solution using static attributes does not work due to the state of the objects. Although it seems unreasonable, what do you think about transform the container in a singleton to ensure the persistence?
    About the use of XML in IoC, I have not had time to properly analyze your framework and I have yet to get used to the concepts of IoC, do you think that a new implementation of the provider using XmlSerializermaner would do the trick?

    • Hi,

      Transforming the container in to a singleton hides a big risk of memory leaking. This is the only thing you need to be aware of.
      I did not think about a way to use an xml configurator, but I bet it would be easy enough to implement (using reflection).

  12. Hi, great articles, I was looking for DI framework for Unity, plus some theory in IoC, for a while now and this seems like exactly what I wanted.
    My concern is about performance of the code, as I and our team are pure game developers, we are always worried about it, so we try not to rely on interfaces or getters/setters and use more “accesible” code like public variables or static classes, etc.
    So you can imagine that trying to introduce a new paradigm like this in a team not used to these techniques can be very difficult.
    What are your thoughts and experience in this matters, performance of the code using DI on a full production project, and evangelization of a new paradigm in a team?.
    Thank you.

    • Hello and thanks for the comment.
      Most of the injections happen during the initialization phase so performance should not be an issue. However it is true that injection could happen anytime using factories as well.
      Since my IoC relies on reflection and I did not write any caching method to speed up the injection of known types, I would not use IoC factories to create/inject objects while the game runs, unless it happens sporadically.

  13. Hi, Sebastiano!

    I tried to use your DI container, but looks like I miss something …
    In this sample I am trying to create two different objects:

    public class SimpleClass
    {
    public Guid _id = Guid.NewGuid();
    }

    [TestMethod]
    public void TestBuild()
    {
    var container = new UnityContainer();

    container.Bind().AsSingle();

    var obj1 = container.Build();
    var obj2 = container.Build();
    Assert.AreNotEqual(obj1._id, obj2._id);
    }

    The test fails. So, all objects build by container are singletones?
    Could you please explain me this behaviour?
    Thank you in advance

    • Sorry, looks like all signs ‘greater’ and ‘less’ were eaten by blog engine.
      In my test I am trying to create two SimpleClass objects one by one.
      container.Build() returns the same instance twice

      • Thanks for the comment, this is indeed the intended behavior…that’s why it is called AsSingle! (btw they are not singletons, they are just the same instance)

        if you want different instance of the same class, you should use factories…let me know if you need an example.

        • Hi, Sebastiano

          Thank your article, i am studies this framework and try to using in my project, now.
          I hope to know how to use factories in your container, is it like your MonsterFactory in the example, or have other method to do?
          If there has another method, can you give me the example?

  14. Hi Sebastiano,

    I just started coding with Unity3D (only about a week in), but it only took me a couple days to realize that I needed a DI container of some sort. So I’m very happy to have found your project! This looks like a big step in the right direction.

    I haven’t used Ninject before, but I have used Castle Windsor extensively with my business development MVVM / MVC style projects. So I do know how complex it can be considering that these containers not only handle instantiating objects, but that they also manage the “lifetime” of the objects and handling disposal in many cases (unless specifically instructed not to, as in when a dependency is registered as a Transient in Castle Windsor).

    Can you elaborate on why you think Ninject is overly complicated for use with Unity / game development? Is it just that you just want the container to simply instantiate and inject the objects, but you do not want the container to try to manage their lifetimes? This way, you are responsible for destryoying all created objects?

    Thanks

    • Hello Jordan, thanks for the feedback. Since you are new to Unity I have to highlight that the real reason why I needed an IoC container is the lack of a proper way to inject dependencies inside monobehaviour objects in Unity. Of course, with the introduction of a composition root, I am also able to avoid to use monobehaviour objects when they are not needed.

      The original version of Ninject does not work in Unity, Uninject should, but when it came out my version was already enough. Point is that I am working on a relatively big project and I do not need nothing more, while Ninject is quite a huge project. Never understood why an IoC should be so complicated. My IoC lacks some features, but I never needed more (I am working on a new version, which is better, but not much different).

      I do not know exactly what you mean with the management of the lifetime, I do not know ninject so well anyway. In everycase once a dependency is injected, a new reference is obviously created, so the IoC framework cannot really do much about it.

      In my simple framework, the objects are alive as long as the container is alive (and of course other objects reference to them). Remember c# uses garbage collection.

      Can you tell me some features from ninject that you really find useful? So far the only one I am really missing is the injection by constructor. Another interesting feature could be to use hierarchical containers, but I never had the need for it so far.

  15. Well I have 1 feature idea, don’t know if it is already available in your IoC container or in Ninject but may be usefull:

    When a container is destroyed it may print a log of wich dependencies are not used. If codebase is wellwritten and everything is concern separated, it is likely that after some refactoring (maybe removing a dependency) the log shows that some classes were not used.

  16. Hi my name is Antonio Zamora and I’m very interested in game programming patterns. I would really like to share my thoughts with you (I’m not an native speaker so please excuse my english).

    As you I have worked with robotlegs before and I praised the philosophy it had. I loved actionscript and I felt very good working with the adobe platform. But later adobe seemed to take some bad decisions that I didnt share so I searched for a new place to look at.

    I discovered unity and I liked the whole idea of gameobjects. As you mention the gameobject can have a view or not. This remembered me the while idea of mediators and actors from robotlegs so as you I decide to follow some simple rules.

    One of them was, as yoo mentioned, forget about the use of gameObject.Find() Since then I’ve tried to understand well the whole model. I decided that for each prefab I have to had a Mediator, so you get to see something like this:
    StarItemPrefab.prefab
    StartItemMediator.cs

    With this I try to follow your rule number 2 “MonoBehaviours are reusable, single responsibility classes.”

    So far I have been really happy, because my designers only have to pay attention to the mediator on each prefab, be it to tweek an speed or to increase a variable that is exposed.

    I have been always interested in this approach of programming but sometimes this mediators keep growing and growing. I try my best to extend its functionality by adding components but well, sometimes the work have to be done.

    Finally one last question, how do you approach your number 5 rule:”The behaviour of a GameObject should be extended adding MonoBehaviours instead of adding methods to a single MonoBehaviour.”

    What do you do normally when you are implementing you monobehaviours, do you do a lot and a lot of components? or do you tend to keep the gameobjects as clean as components as posible?

    Thanks for the post.

    • the idea is to create as simple as possible monobehaviours and add as many as you need. So let them do just one thing, if you need 10 different things, use 10 different components on the same GameObject.

      For the MVC (or better MVVM) pattern is a little bit more complicated due to the Unity limitations, but it is still doable. My idea is that the Monobehaviour becomes the view or the model, sometimes both and a presenter is injected in to it. The view redirects the events (awake, start, update, oncollision, onmousedown etc..) to the presenter (controller or viewmodel) which decides what to do.

  17. Great article! Thanks for your work. Unity 3D has many specific features and you offered amazing ideas and tools for resolve it. I used a Singleton approach before (DI ideas) as a start as a single way to manage objects but for complex projects such way is fall down road. Also, you are right concerning MonoBehavior using without any appropriate foundation.
    Agree!
    Unity 3D Platform Lead at XIM Wireless

  18. IoC solutions for Unity | StrangeIoC

Leave a Reply