{"id":73,"date":"2021-10-24T07:45:26","date_gmt":"2021-10-24T07:45:26","guid":{"rendered":"https:\/\/docs.sisus.co\/inity\/?p=73"},"modified":"2026-01-08T07:19:34","modified_gmt":"2026-01-08T07:19:34","slug":"why-init-args","status":"publish","type":"post","link":"https:\/\/docs.sisus.co\/init-args\/introduction\/why-init-args\/","title":{"rendered":"2. Why Init(args)?"},"content":{"rendered":"<p>To fully grasp the advantages that Init(args) can unlock, it&#8217;s essential to first understand a key design principle in software engineering: <strong>inversion of control<\/strong>.<\/p>\n<p>In a nutshell, inversion of control means that instead of classes independently retrieving the objects they need, those objects are provided to them by other classes.<\/p>\n<p>This approach comes with several benefits, such as making it very easy to swap out delivered objects with different ones.<\/p>\n<p>Typically, inversion of control can be achieved by passing the objects that a client needs to it via its constructor:<\/p>\n<pre class=\"western\"><span style=\"color: #800080;\"><span style=\"color: #800000;\"><b>using <\/b><\/span><\/span><span style=\"color: #000000;\">UnityEngine<span style=\"color: #800080;\">;\r\n<\/span><\/span>\r\n<span style=\"color: #000000;\"><span style=\"color: #800000;\"><b>class <\/b><\/span><span style=\"color: #800080;\">Player<\/span><\/span>\r\n<span style=\"color: #800080;\">{<\/span>\r\n<span style=\"color: #000000;\">    <span style=\"color: #000000;\">IInputManager InputManager<span style=\"color: #800080;\">;<\/span><\/span><\/span>\r\n<span style=\"color: #000000;\">    <span style=\"color: #000000;\">Camera Camera<span style=\"color: #800080;\">;<\/span><\/span><\/span>\r\n\r\n<span style=\"color: #000000;\"><span style=\"color: #800000;\"><b style=\"color: #800000;\"><span style=\"color: #800000;\">    public <span style=\"color: #800080;\">Player<\/span><\/span><\/b><b style=\"color: #800000;\"><span style=\"color: #800080;\"><span style=\"color: #808030;\">(<\/span><\/span><\/b><\/span><\/span><span style=\"color: #000000;\"><span style=\"color: #000000;\">IInputManager inputManager<span style=\"color: #808030;\">,<\/span> Camera camera<\/span><span style=\"color: #808030;\">)<\/span><\/span>\r\n<span style=\"color: #000000;\">    <span style=\"color: #800080;\">{<\/span><\/span>\r\n<span style=\"color: #000000;\"><span style=\"color: #800000;\"><b style=\"color: #800000;\">        this<\/b><\/span><span style=\"color: #800080;\">.<\/span>inputManager <span style=\"color: #808030;\">=<\/span> inputManager<\/span><span style=\"color: #000000;\"><span style=\"color: #800080;\">;\r\n<\/span><\/span><span style=\"color: #000000;\"><span style=\"color: #800000;\"><b style=\"color: #800000;\">        this<\/b><\/span><span style=\"color: #800080;\">.<\/span>camera <span style=\"color: #808030;\">=<\/span> camera<span style=\"color: #800080;\">;<\/span><\/span>\r\n<span style=\"color: #000000;\">    <span style=\"color: #800080;\">}<\/span><\/span>\r\n<span style=\"color: #800080;\">}<\/span><\/pre>\n<p>However, Unity\u2019s <span style=\"background-color: #f2f4f5; color: #222222; font-family: monospace, serif; font-size: 15px;\">MonoBehaviour<\/span> or <span style=\"background-color: #f2f4f5; color: #222222; font-family: monospace, serif; font-size: 15px;\">ScriptableObject<\/span> classes don&#8217;t support constructor arguments, making it challenging to apply inversion of control.<\/p>\n<p>This situation often leads developers to rely on things like the <strong>Singleton<\/strong> pattern instead, leading to classes being rigidly bound together in a tangled web of dependencies.<\/p>\n<pre class=\"western\"><span style=\"color: #800080;\"><span style=\"color: #800000;\"><b>using <\/b><\/span><\/span><span style=\"color: #000000;\">UnityEngine<span style=\"color: #800080;\">;<\/span><\/span>\r\n\r\n<span style=\"color: #000000;\"><span style=\"color: #800000;\"><b>class<\/b><\/span> Player <span style=\"color: #808030;\">:<\/span> MonoBehaviour<\/span>\r\n<span style=\"color: #800080;\">{<\/span>\r\n<span style=\"color: #000000;\">    <span style=\"color: #800000;\"><b>void<\/b><\/span><span style=\"color: #800080;\"> Update<\/span><span style=\"color: #808030;\">()<\/span><\/span>\r\n<span style=\"color: #800080;\">    {<\/span>\r\n<span style=\"color: #000000;\"><span style=\"color: #800000;\"><b>        if<\/b><\/span><span style=\"color: #808030;\">(<\/span>InputManager.Instance<span style=\"color: #808030;\">.<\/span>Input<span style=\"color: #808030;\">.<\/span>y <span style=\"color: #808030;\">&gt;<\/span> 0f<span style=\"color: #808030;\">)<\/span><\/span>\r\n<span style=\"color: #000000;\">        <span style=\"color: #800080;\">{<\/span><\/span>\r\n<span style=\"color: #000000;\"><span style=\"color: #800000;\">            <b style=\"color: #800000;\">var<\/b><\/span><span style=\"color: #000000;\"> speed <\/span><span style=\"color: #808030;\">=<\/span> <span style=\"color: #008000;\">0.2<\/span><span style=\"color: #006600;\">f<\/span><span style=\"color: #800080;\">;<\/span><\/span>\r\n<span style=\"color: #000000;\"><span style=\"color: #800000;\">            <b style=\"color: #800000;\">var<\/b><\/span><span style=\"color: #000000;\"> distance <\/span><span style=\"color: #808030;\">=<\/span><span style=\"color: #000000;\"> Time<\/span><span style=\"color: #808030;\">.<\/span><span style=\"color: #000000;\">deltaTime <\/span><span style=\"color: #808030;\">*<\/span><span style=\"color: #000000;\"> speed<\/span><span style=\"color: #800080;\">;\r\n<\/span><\/span><span style=\"color: #000000;\">            transform<span style=\"color: #808030;\">.<\/span>Translate<span style=\"color: #808030;\">(<\/span>Camera<span style=\"color: #808030;\">.<\/span>main<span style=\"color: #808030;\">.<\/span>transform<span style=\"color: #808030;\">.<\/span>forward <span style=\"color: #808030;\">*<\/span> distance<span style=\"color: #808030;\">)<span style=\"color: #800080;\">;\r\n<\/span><\/span><\/span>        <span style=\"color: #800080;\">}\r\n    }<\/span>\r\n<span style=\"color: #800080;\">}<\/span><\/pre>\n<p>While this does accomplish the job of retrieving the instance, it also comes with some pretty severe negative side effects that may end up hurting you in the long run &#8211; especially in larger projects.<\/p>\n<h4>\ud83d\udd0d <strong>Hidden Dependencies<\/strong><\/h4>\n<p>Dependencies are scattered all over the class rather than being clearly and statically defined in one place. This obscures what requirements must be met for the component to function correctly.<\/p>\n<p>For example, while you can instantiate the above <code>Player<\/code> at any time using <code>GameObject.AddComponent()<\/code>, or attach it to any GameObject using the Inspector, there&#8217;s no way for you to know in either case that an <code>InputManager<\/code> and a main camera must also exist somewhere in the scene for it to actually work!<\/p>\n<h4>\ud83e\uddea <strong>Testability<\/strong><\/h4>\n<p>It tends to make it near impossible to write unit tests. If the Player class depends on a specific InputManager singleton object, you can\u2019t swap it with a simpler test double during tests, nor modify it its state in any way without the potential for undesired side effects.<\/p>\n<h4>\ud83d\udd27 Maintainability<\/h4>\n<p>If you need to change a service to a different one &#8211; say, <code>InputManager<\/code> to\u00a0<code>NewInputSystemManager<\/code> &#8211;\u00a0you&#8217;ll need to update every class that uses the old one.<\/p>\n<p><!--EndFragment --><\/p>\n<h4>\ud83e\udde9 <strong>Adaptability<\/strong><\/h4>\n<p>You lose the flexibility to swap implementations based on context, such as using <code>MobileInputManager<\/code>on mobile platforms and <code>PCInputManager<\/code> on desktop platforms.<\/p>\n<h4>\ud83d\udeab<strong>Reusability<\/strong><\/h4>\n<p>Tightly coupled systems are harder to reuse across projects. For instance, if your <code>CameraController<\/code> depends on several other specific classes, which all depend on several other specific classes, you won&#8217;t be able to migrate it to another project without a lot of rewriting.<\/p>\n<h2>Enter Init(args)<\/h2>\n<p><!--EndFragment --><\/p>\n<p>Init(args) addresses all of these issues by making it trivial to achieve inversion of control in Unity, with the introduction of the new\u00a0<b>Init<\/b><strong> function<\/strong>:<\/p>\n<pre><span style=\"color: #800000;\"><b><span style=\"color: #800080;\">using <\/span><span style=\"color: #000000;\">Sisus<span style=\"color: #800080;\">.<\/span>Init<span style=\"color: #800080;\">;<\/span><\/span>\r\n\r\n<\/b><\/span><span style=\"color: #800000;\"><b>class<\/b><\/span><span style=\"color: #800080;\"> Player <\/span><span style=\"color: #808030;\">:<\/span><span style=\"color: #800080;\"> MonoBehaviour<\/span><span style=\"color: #800080;\"><span style=\"color: #000000;\"><span style=\"color: #808030;\">&lt;<\/span><\/span><span style=\"color: #000000;\">IInputManager, Camera<span style=\"color: #808030;\">&gt;<\/span><\/span>\r\n{\r\n<\/span><span style=\"color: #000000;\"><span style=\"color: #800000;\">    IInputManager inputManager<span style=\"color: #800080;\">;<\/span>\r\n    Camera camera<span style=\"color: #800080;\">;<\/span>\r\n\r\n    <b style=\"color: #800000;\">protected override void<\/b><\/span><span style=\"color: #800080;\"> Init<\/span><span style=\"color: #808030;\">(<\/span><\/span><span style=\"color: #000000;\">IInputManager inputManager, Camera camera<span style=\"color: #808030;\">)\r\n<\/span><\/span><span style=\"color: #000000;\">    <span style=\"color: #800080;\">{\r\n<\/span><\/span><span style=\"color: #000000;\"><span style=\"color: #800000;\"><b style=\"color: #800000;\">            this<\/b><\/span><span style=\"color: #800080;\">.<\/span>inputManager <span style=\"color: #808030;\">=<\/span> inputManager<\/span><span style=\"color: #000000;\"><span style=\"color: #800080;\">;\r\n<\/span><\/span><span style=\"color: #000000;\"><span style=\"color: #800000;\"><b style=\"color: #800000;\">            this<\/b><\/span><span style=\"color: #800080;\">.<\/span>camera <span style=\"color: #808030;\">=<\/span> camera<span style=\"color: #800080;\">;<\/span>\r\n<\/span>    <span style=\"color: #800080;\">}\r\n}<\/span><\/pre>\n<p>This makes all dependencies explicit, and makes the code testable, modular and maintainable by default.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>To fully grasp the advantages that Init(args) can unlock, it&#8217;s essential to first understand a key design principle in software engineering: inversion of control. In a nutshell, inversion of control means that instead of classes independently retrieving the objects they need, those objects are provided to them by other classes. This approach comes with several ..<\/p>\n<div class=\"clear-fix\"><\/div>\n<p><a href=\"https:\/\/docs.sisus.co\/init-args\/introduction\/why-init-args\/\" title=\"read more\">Read more<\/a><\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[3],"tags":[],"_links":{"self":[{"href":"https:\/\/docs.sisus.co\/init-args\/wp-json\/wp\/v2\/posts\/73"}],"collection":[{"href":"https:\/\/docs.sisus.co\/init-args\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/docs.sisus.co\/init-args\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/docs.sisus.co\/init-args\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/docs.sisus.co\/init-args\/wp-json\/wp\/v2\/comments?post=73"}],"version-history":[{"count":25,"href":"https:\/\/docs.sisus.co\/init-args\/wp-json\/wp\/v2\/posts\/73\/revisions"}],"predecessor-version":[{"id":1092,"href":"https:\/\/docs.sisus.co\/init-args\/wp-json\/wp\/v2\/posts\/73\/revisions\/1092"}],"wp:attachment":[{"href":"https:\/\/docs.sisus.co\/init-args\/wp-json\/wp\/v2\/media?parent=73"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/docs.sisus.co\/init-args\/wp-json\/wp\/v2\/categories?post=73"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/docs.sisus.co\/init-args\/wp-json\/wp\/v2\/tags?post=73"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}