Inversion of Control (IoC) means to create instances of dependencies first and latter instance of a class (optionally injecting them through constructor), instead of creating an instance of the class first and then the class instance creating instances of dependencies. Thus, inversion of control inverts the flow of control of the program. Instead of the callee controlling the flow of control (while creating dependencies), the caller controls the flow of control of the program.
Can I see a game built by using Unity IoC framework?
In the repository, you will see a unity scene located at Assets/App/Scene/Game.unity
It’s a game version of mine sweeper written in unity IoC
Before that, I already developed a similar project using Zenject, then I realized zenject is a overkill for what I need, so I started developing a new one more fit to my needs. Here is a link to the old project
Where can I found more tutorials about Unity IoC?
I also made some videos on my youtube channel, but my voice isn’t clear, so sorry about that.
Not only Unity IoC but I also talked about Photon server, Firebase, UniRx and many interesting things!
If you want to use Unity IoC, then I think my videos will be helpful for you.
How to get started?
Download the project, then using UnityIoC; namespace in the top of your C# files.
You will want to create a context object from Context class.
Context context = new Context();
Now we have the context, that will resolve most of objects for your classes.
I intend to make C# attributes to decorate your code! Let me show you some of them!
[Binding] should be placed before class keyword
[Binding(typeof(AbstractClassOrInterface)] means you will bind the abstract code to this conrete class when you use the context to resolve the abstract type.
There are some attributes to resolve object using binding you defined, they are singleton, transient, component, etc. They should be placed before a class member (fields, properties, methods, etc)
[Singleton] : If you want to context resolve an object as a singleton.
[Transient] : If you want to context resolve an object as a singleton.
[Component] : used only for unity objects. these objects will be get from the gameObject or created by adding new component to the gameObject
And more to come,...
Instead of using attributes, you can just write a line of code to resolve
Context context = new Context();
Var instance = context.Resolve<TypeOfClassYouWant>();
Then you got the instance :)
What if the instance return from context is null ???
well , in that case, first look at console to see if there is any exception thrown, I throw exceptions when there are invalid operations happened in the context.
You can copy the unity logs then email me if you cannot solve the issue. Maybe something went wrong.
What have I done so far to resolve dependencies in Unity3d?
Unity3d provides a few of ways to resolve your dependencies. Let’s think about it when your mono behaviour need an instance of rigidBody!
1. You can use the modifier public fields or using [SerializeField] to expose non-public fields.
E.g: public Rigidbody rigidBody; [SerializeField] Rigidbody rigidBody
Then you have to select objects then drag & drop them from unity editor to resolve the rigidBody dependency which your behaviour needs.
2. You can use the GetComponent or Find... static methods from UnityEngine.Object
Well, by this way, you can add or get component from the gameObject or from the other objects in the scene.
There are convenient methods that Unity already provided, but you also write that code time to time, and there are issues, e.g: Find... methods only work for non-disable GameObjects while GetComponent cannot get the references for some “Manager objects” that could be a singleton.
What’s wrong with the Singleton?
I saw Many people love singleton, they say it’s so convenient, (I think so too)
Also many people hate singleton, they say it’s an anti-design pattern. (Maybe they don’t tell you why)
Personally I have been using singleton for quite a long time, I also wrote generic singleton classes for unity, you can check it here
However, using singleton is not best practice in programming. I can tell you I saw so many teams who have to fix their bugs hopelessly just because they all using SINGLETON which are public static accessible from every where in their code.
Without using it properly, Singleton will be the root of the code smell.
You also are probably writing the same “manager objects” using singleton. “Game manager, sound manager, Level manager, etc”.
Singleton is only one instance in the program, and other objects can access the singleton by a shared static instance.
It means you cannot create a second one. E.g, I want to test GameClient class by creating 2 clients and let them communicate each other. If you write the GameClient as singleton, it’s impossible to even write a unit test for the that functionality.
You also will not have abstraction, polymorphism and inheritance for your OO classes. Therefore your code is not a true OOP!
By modifying the singleton from everywhere, you are making your code vulnerable for side effects which can cause the serious bugs in common cases.
You can not change the behaviour of your code at the runtime, you have to edit the source and recompile, then run again the application to see your changes.
If you still want to use singleton, it’s your decisions, I won’t make you stop using it.
Licence and contribute to this project?
It’s free to use in your projects, however I do not allow to redistribute the source code in any case, and I want to know if this IoC is helpful for your projects, please send me an email about your development when you use my source code. The same way if you want to contribute for unity IoC.