Notifications
Article
I love it when all of tests passed!
Updated 6 months ago
152
1
Learn the art of testable code in Unity3d
https://github.com/game-libgdx-unity/Unity-IoC
https://docs.google.com/document/d/1xVOoFa0KxrTnqfogQ_s9qoCgWL5meJnlkENV4_WaylE/edit#
Unity IoC passed major tests!
What is IoC?

I found an answer on stackoverflow
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.
https://stackoverflow.com/questions/3058/what-is-inversion-of-control
Don’t worry if you still don’t get it, I’ll show you how it works by examples & actions :)
Why should I need an IoC?

Well if you have been using DI (Dependency Injection) for a while, maybe this is the first question you have. So why do you need an IoC container as opposed to straightforward DI code?
I can give you an example of DI:
In a good day, You just realize that you need an instance of ProductLocator for your ShippingService class.
Okay then create it by var pl = new ProductLocator();
Why you need to create it? Because you have another object is ShippingService and you need to pass a ProductLocator to the ShippingService’s constructor!
So this is how you should create ShippingService: new ShippingService(new ProductLocator());
Wait, what if ShippingService’s constructor have more than one parameter? E.g they have 5 or 10, even these parameters also have their own dependencies? And finally you may end up your code like this
var svc = new ShippingService(new ProductLocator(),
new PricingService(), new InventoryService(),
new TrackingRepository(new ConfigProvider()),
new Logger(new EmailLogger(new ConfigProvider())));
Ridiculously crazy, right?
I know this example maybe too exceeding, just to show you benefits of an IoC. However if you have used an IoC, then you can let the IoC create the instance of ShippingService for you simply:
IoC context = new IoC();
var svc = context.Resolve<ShippingService>();
Ridiculously simple, right?
As you can see everything done with the help from a simple IoC container, it resolves every dependencies of your objects for you magically!
That’s one of goals I want to achieve from developing this project!
Other benefits can be
You write Loose coupling classes, they are dependent from each other.
Your code is testable, using unity test runner or other automatic test tools.
Testable code is the good code. If you are not sure why, you should google it :)
Reduce lines of code you have to write (or copy & paste)
You don’t waste your time to resolve the dependency for your class anymore, let IoC handle it!
How to get the source code?

All of my source code are free to download at my github, this repository
https://github.com/game-libgdx-unity/Unity-IoC-inverse-of-control-dependency-injection-
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
https://github.com/game-libgdx-unity/minesweeper
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.
https://www.youtube.com/playlist?list=PLrxnIke4BNsTyVk2piv7PclE5aDadmfIB
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!
Create bindings
[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.
Resolve objects
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
https://github.com/game-libgdx-unity/TD/blob/master/Assets/Scripts/Core/SingletonBehaviour.cs
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.

Thanks for reading!
Vinh
Full Stack - Programmer
6
Comments
Vinh
5 months ago
Full Stack
# Unity-IoC The project has been accepted. It's available to download for free right now! Introduction video https://www.youtube.com/watch?v=y0pQth1mnzo Connect with me on Unity3d community https://connect.unity.com/u/vinh-swk2 You can download this asset from unity3d asset store, https://assetstore.unity.com/packages/tools/integration/universal-resolver-138872 however I would recommend you download from this GitHub repository. for latest updates and bug fixes. https://github.com/game-libgdx-unity/Universal-Resolver/ Online documentation. https://docs.google.com/document/d/e/2PACX-1vRICY-Xj7f-Tlg0TLgALpe24w6IjPIrpFTPIwKZfxUtrVD8IV74Gb9qVOqm12_ORu02is9b7cf6u1YY/pub Implements for Unity in fields of IoC, Reactive programming, Firebase, Photon Server, etc. Unity3d Resolver is an Unity3d IoC Framework comes with combine of binding settings from UnityProject. C# Attributes allow to resolve your fields, constructors, methods or properties as [Component], [Singleton] and [Transient]. There are a lot of test scenes in the sample folder. Also I developed a minesweeper game using this framework, inside the sampleGame folder. This asset supports - Resolve both C# & Unity Component objects - Build games on Editor, Standalone, iOS, Android - Write loose-couple and testable C# code. - Using scriptable setting files to do binding, it means you don't need to change the code to change the behavior - You just need to change setting files and run or restart your game to have changes applied. Programmer & Document writer: Vinh Vu Thanh Contact email: Mrthanhvinh168@gmail.com Thanks for reading!
0