If it’s the first time you visit my blog, please don’t forget to read my main articles on the subject before to continue this post:

It’s finally time to share the latest version of my Inversion of Control container, which I named Svelto IoC, which I will keep updated from now on. This new version is the current IoC container that Freejam is using for the Unity3D game Robocraft (http://www.robocraftgame.com).

Thanks to the possibility to use the library in production, I could analyse in depth the benefits and disadvantages in using extensively an IoC container on a big project with a medium sized team of programmers. I am preparing an exhaustive article on the subject, but I am not sure when I will be able to publish it, so stay tuned.

The new IoC container is structurally similar to the old one, but has several major differences. In order to use it, a UnityRoot specialised monobehaviour must still be created. The class that implements ICompositionRoot is the Compositon Root of the project. The game object holding the UnityRoot monobehaviour is the game context of the scene.

All the dependencies bound in the Composition Root, will be injected during the Unity Awake period. Dependencies cannot be used until the OnDependenciesInjected function or the Start function (in case of dependencies injected inside monobehaviours) are called. Be careful though, OnDependenciesInjected is called while the injection waterfall is still happening, however injected dependencies are guaranteed to have, on their turn, their dependencies injected. Dependencies are not guaranteed to be injected during the Awake period, therefore you shouldn’t use injected dependencies inside Monobehaviour Awake calls.

Other changes include:

  • Monobehaviours that are created by unity after the scene is loaded, don’t need to ask explicitly to fill the dependencies anymore. They will be automatically injected.
  • Monobehaviours cannot be injected as dependency anymore (that was a bad idea).
  • Dynamically created monobehaviours have always dependencies injected through factories (MonoBehaviourFactory and GameObjectFactory are part of the framework).
  • Now all the contracts are always injected through “providers”, this simplifies the code and makes it more solid. Also highlights the importance of providers in this framework.
  • A type injection cache has been developed, therefore injecting dependencies of the same type is way faster than it used to be.
  • It’s now possible to create new instances for each dependency injected, if the factory MultiProvider is used explicitly.
  • You can create your own provider for special cases.
  • Improved type safety of the code. It’s not possible anymore to bind contracts to wrong types. For this reason AsSingle() has been substituted by BindSelf().
  • Various improvements and bug fixes.
  • Dependencies can be injected as weak references automatically.

What is still need to do:

  • Improve the documentation and explain the bad practices
  • Add the possibility to create hierarchical context and explain why they are necessary
  • Add the possibility to inject dependencies by construction, in order to reduce the necessity to hold references.
  • Explain how to exploit custom providers.

The new project can be found at this link: https://github.com/sebas77/Svelto-IoC

 

0 0 votes
Article Rating
Subscribe
Notify of
guest

21 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
André "Intentor" Martins
André "Intentor" Martins
9 years ago

Thanks for sharing the newest version of the container!

After reading the post, I was wondering why you said that injecting into MonoBehaviours was a bad idea. Since the very first version of your container, I always enjoyed this concept and I even carried it on to my current container, Adic. With a little bit of caching, this has never been a problem in any game I implemented it.

Why did you changed your mind about it?

André "Intentor" Martins
André "Intentor" Martins
9 years ago

Interesting thoughts on the problem! However, after reading your P.S., it made me think that maybe I understood your observation all wrong. In fact, injecting MonoBehaviours somewhere is really a bad idea, as you pointed out – missing references can be a mess! However, as you also indicated, injecting dependencies INTO MonoBehaviours is no problem at all – and that’s where I think got it all wrong: I was thinking that wiring dependencies into MonoBehaviours was a bad idea. Anyway, your observations were interesting, as usual. I’ll wait until the article to read more details about your decisions on the… Read more »

sopwerk
sopwerk
8 years ago

I like a lot your tight implementation and minimalistic approach.
One question though – why no container hierarchies?
Simple parent-children hierarchy would be quite easy to add into your framework.
Have you never meet the need?

sop3000
sop3000
8 years ago

My most frequent use case is kind of builder/factory that uses child container to wiry dependencies for a complex object assembled from several components. Where parent container provides access to the global (often singleton) services.

For my experiments, I’ve just added a simple single-parent container support into your framework – like 6 new lines or so.
I think its worth it.

(but now I see a need to have nested lookup contexts too… no, better to stop right now. 😉

sop3000
sop3000
8 years ago

Please find below an example code of my usage of the hierarchical containers. The idea is simple: root container defines all “globally” accessible services (app-wide singletons), while children containers are used to assist in wiring together of the “complex” objects – e.g. Vehicles in my example. VehicleBuilder class defines a child container with all necessary components required to construct a new Vehicle instance. For simplicity, the container is discarded after the vehicle is constructed. (some kind of nested scope support could help here for price of added complexity in the framework code, but I’m not sure it’s worth it). The… Read more »

sop3000
sop3000
8 years ago

pastebin… of course. sorry, didn’t come to my mind.
here is the link to the code example:

http://pastebin.com/0k1DmmCe

Andrey Tevelyev
Andrey Tevelyev
8 years ago

Hi. That was very interesting to find your site with the IoC framework for Unity, as I have just developed my own framework, and it looks very similar feature and usage cases wise. It’s funny how our solutions are matching, especially with factory things, and also the approach to the mono behaviours 🙂 I wanted to comment on injection of MonoBehaviour as I think it can be still needed sometimes. In my project i have a generic view, that is MonoBehaviour and is created through the factory dynamically. So for different object types, the different instances of the generic view… Read more »

Andrey Tevelyev
Andrey Tevelyev
8 years ago

Hi. I have several situations where I do inject MonoBehaviours. E.g. have a single coroutine manager for the whole application to start all coroutines on, that i can inject to any objects that start coroutine. Or for example I have a presentation that is aware of its view and injects the view. When instantiating the presentation, I want the view to be resolved automatically together as dependency, and instantiated. There can be many other cases, and while I’m also thinking, that the usage of MonoBehaviour should be careful, I think that I don’t want to limit of how people might… Read more »

Andrey Tevelyev
Andrey Tevelyev
8 years ago

WordPress swallows less and greater charaxters so the class signature was this with [] instead of “less-greater” brackets (I don’t know how to screen them)
public class MergePanelUI [T, TChild] : ContextMonoBehaviour, IMergePanelUI[T, TChild]

sdemius
sdemius
8 years ago

Hello! Thanks for your IoC container. I am started using it in our Unity3D project. I have one question. You probably use the IoC container in a multiplayer game. In a multiplayer game GameObject should have NetworkBehaviour instead of MonoBehaviour component. The question is how to create a network GameObjects? When the network objects are created on the server scene, they will automatically appear on client scenes. How to control it? The same should be done for the Player GameObject. You can of course override the handlers to control spawn players and objects, but maybe you already have a ready-made… Read more »

Dario
Dario
6 years ago

Thank you for this update. Great work, as always. Regarding the containers hierarchies i tried doing that (in cpp) and Was never Happy with the result, actually i preferred ti keep multiplex Independent containers from which some instances could be “shared” but that is fine manually. The fact is that Sharon bindings in a hierarchies way makes much less obvious which implementation is choosen

Dario
Dario
6 years ago
Reply to  Dario

Ehm seems this is off post Sorry. I Just saw the last update in github