I’ve finally decided I’m going to use an Inversion of Control Container as a framework to avoid any fixed dependancies of my project. Since self making a IoC Container would be a beesch, I’ve decided to download one. There’s two decent ones, however I’m not sure which one to go with:
User Reviews
Both have the same number of reviews, with 5 stars on each. So they’re both decent in terms of user feedback.
Tutorials / Documentation
StrangeIoC has 3 different people with YouTube playlists based on StrangeIoC examples, as well as the creators tutorial youtube series (2 part). While Zenject has no online tutorials, but a massive GitHub repo with a big written API and documentation, with tutorials.
Developer Activity
Both are responsive developers.
Features
Zenject can create ITickable objects, where you can create a ticking order so you can choose the order each object will receive their ‘Update’ function. Plus Zenject is a more lightweight non-intrusive framework. While StrangeIoC is larger, but presumably more robust (? Total guess lol). Zenject also comes with a Editor extension which auto creates UML object graphs for you to understand your project and share it with designers/producers ect.
Current Version
Strange IoC has updated from 4.3.1, but works on current version of Unity. While Zenject was submitted with Unity 5.1. So I’m presuming that’ll work with 5.2 as well.
With the thoughts I’ve thrown into the mix right now, and with anyone else’s experience. Which one would you guys choose, if you needed to choose one? If you’ve used one already, or have a preference? Or just can see a clear difference from what I’ve mentioned so far.
uFrame Game Framework - Not actually an IoC Container - Several very long Reviews with high ratings. It also costs $90, but has lots and lots of graphs and things. Possibly overkill?
I tried strangeioc, at first. It has some interesting things. I like the signals implementation so much that I duplicated it in Zenject. However, strange has an anti-game object and anti-scriptable object mentality. I read some posts where users, who were asking for best practices on using prefabs and scriptable objects, were recommended to import their data from xml or json files. I saw that as the container designers discarding a huge benefit of Unity, which is the inspector and linking assets together. Plus, it meant that I would have had to write custom tools for building each type of complex data structure that I would want to import or use. No thanks.
I’m currently building with Zenject. It’s nice. I’d recommend it.
I’ve only played with adic for an evening. It seems on par with Zenject, and has good trajectory to become a valuable container. It’s worth keeping an eye on. I haven’t done more with it since I’m still experimenting with Zenject. Also, zenject seems to have a slightly larger community to draw from (but only slightly).
We tried both and ended up using Zenject since at the time of implementation (a year and a half ago), it was the most robust one available; it simply works and has little overhead.
However, if you’re targetting consoles, I’d suggest taking a deeper look at it since it uses some fancy Reflections and might not be portable to all platforms.
We are waiting for our Xbox One kits to arrive and finger crossed are hoping it will work out of the box.
We’ve been having good success with StrangeIoC and it’s MVCS architecture. I’ve found ways of making it more “unity-friendly” by wiring up Scriptableobjects and Isolated Monobehaviours in a sane, reasonsable fashion, instead of using xml or json. All of these frameworks use reflection with generics and may have issues on Consoles with the old console AOT compiler. IL2CPP may alleviate some of these issues but it may be possible to use them on console if you workaround with non-generic versions of the calls.
At this point, between Zenject and Strange, it’s mostly a matter of preference.
While the codebase itself is under NDA, I can give you the gist of it:
ContextViews are Monobehaviours.
Wire up references to a sub-class of that context view.
Make public accessors (I never expose serialized data as public or protected if I can get a way with it, I use [SerializeField]).
Inside the Context, get the context view and cast it to the appropriate type.
Get and use the serialized data from the public accessors while wiring up the bindings.
It’s not as convoluted as it sounds, and there’s definitely ways to improve it further, but we use this for serializing a scene navigation graph for a Unity 5.2 project. It lets any “navigable” scene be the one to load the scene data into our injected navigator class so any scene can navigate to any other scene and the proper loading dependencies are satisfied.
All of the navigation is defined in a ScriptableObject with an editor for setting up the application’s nav graph. This setup even lets us dynamically load scene targets after the bootstrap phase, so we could have DLC scenes loaded from an asset bundle.
All of the navigation classes, data models for loaded/current scenes, and so on are just plain C# classes with interfaces, wired up in strange.