{"id":570,"date":"2024-12-26T12:57:19","date_gmt":"2024-12-26T12:57:19","guid":{"rendered":"https:\/\/docs.sisus.co\/init-args\/?p=570"},"modified":"2026-06-23T06:24:12","modified_gmt":"2026-06-23T06:24:12","slug":"inheritance-and-dependencies","status":"publish","type":"post","link":"https:\/\/docs.sisus.co\/init-args\/problems-and-solutions\/inheritance-and-dependencies\/","title":{"rendered":"Inheritance and Dependencies"},"content":{"rendered":"<h1>Problem:<\/h1>\n<p>You have a base class that depends on some services.<\/p>\n<p>You want to create a class that derives from that base class, which depends on some additional services on top of the ones that the base class does.<\/p>\n<pre><span class=\"line_wrapper\">class Base : MonoBehaviour&lt;A, B&gt;\r\n{\r\n    \/\/ The base class depends on some services\r\n    A a;\r\n    B b;\r\n\r\n    protected override void Init(A a, B b)\r\n    {\r\n        this.a = a;\r\n        this.b = b;\r\n    }\r\n}\r\n\r\n<\/span><span class=\"line_wrapper\">class Derived : Base\r\n{\r\n    \/\/ A derived type depends on some additional services\r\n    C c;\r\n    D d;\r\n}<\/span><\/pre>\n<p>Since the Derived class must derive from Base, it can not simultaneously derive from <code>MonoBehaviour&lt;A, B, C, D&gt;<\/code>.<\/p>\n<p>How can Derived be defined in such a way that:<\/p>\n<ol>\n<li>all four dependencies can be provided to it from the outside,<\/li>\n<li>and it will be able to acquire the dependencies automatically at the beginning of the Awake event?<\/li>\n<\/ol>\n<h1>Solution:\u00a0<span class=\"line_wrapper\">IInitializable&lt;T&#8230;&gt;<\/span><\/h1>\n<p>To make it possible to inject all the objects that your derived class and its base class depend on, implement the <a href=\"https:\/\/docs.sisus.co\/init-args\/reference\/iinitializable\/\">IInitializable&lt;T&#8230;&gt;<\/a> interface, and list the types of all their combined dependencies as generic type arguments of the interface.<\/p>\n<p>You will also need to override the <em>bool Init(Context)<\/em> method, to make it acquire all the combined dependencies at the beginning of the Awake event, instead of just the ones that the base class depends on.<\/p>\n<pre class=\"code_syntax\"><span class=\"line_wrapper\">public class Derived : Base, IInitializable&lt;A, B, C, D&gt;\r\n<\/span><span class=\"line_wrapper\">{\r\n    C c;\r\n    D d;\r\n\r\n    \/\/ Implement Init(A, B, C, D) to be able to receive all four dependencies.\r\n    public void Init(A a, B b, C c, D d)\r\n    {\r\n        \/\/ Init the base type\r\n        Init(a, b);\r\n\r\n        \/\/ Init the derived type\r\n        this.c = c;\r\n        this.d = d;\r\n    }\r\n\r\n     \/\/ Override Init(Context) to automatically receive all four dependencies at the beginning of the Awake event.\r\n     protected override bool Init(Context context) =&gt; InitArgs.TryGet&lt;Derived, A, B, C, D&gt;(this);\r\n}<\/span><\/pre>\n<hr \/>\n<h1>Problem<\/h1>\n<p>You have a base class that does not depend on any services.<\/p>\n<p>You want to create a single class that derives from that base class, which does depend on some services.<\/p>\n<pre><span class=\"line_wrapper\">\/\/ The base class with no dependencies\r\nclass Base : MonoBehaviour { }\r\n\r\n<\/span><span class=\"line_wrapper\">class Derived : Base\r\n{\r\n    \/\/ A derived type depends on some services\r\n    A a;\r\n    B b;\r\n}<\/span><\/pre>\n<p>Since the Derived class must derive from Base, it can not simultaneously derive from <code>MonoBehaviour&lt;A, B&gt;<\/code>.<\/p>\n<p>How can Derived be defined in such a way that:<\/p>\n<ol>\n<li>the two dependencies can be provided to it from the outside,<\/li>\n<li>and it will be able to acquire the dependencies automatically at the beginning of the Awake event?<\/li>\n<\/ol>\n<h1>Solution: <span class=\"line_wrapper\">IInitializable&lt;T&#8230;&gt;<\/span><\/h1>\n<p>To make it possible to inject all the objects that your derived class and its base class depend on, implement the <a href=\"https:\/\/docs.sisus.co\/init-args\/reference\/iinitializable\/\">IInitializable&lt;T&#8230;&gt;<\/a> interface, and list the types of all their combined dependencies as generic type arguments of the interface.<\/p>\n<p>You will also need to use <span class=\"line_wrapper\">InitArgs.TryGet during the Awake event<\/span>, to make it acquire all the combined dependencies automatically.<\/p>\n<pre class=\"code_syntax\"><span class=\"line_wrapper\">public class Derived : Base, IInitializable&lt;A, B&gt;\r\n<\/span><span class=\"line_wrapper\">{\r\n    A a; B b;\r\n\r\n    \/\/ Implement Init(A, B) to be able to receive two Init arguments\r\n    public void Init(A a, B b)\r\n    {\r\n        this.a = a;\r\n        this.b = b;\r\n    }\r\n\r\n    \/\/ Use InitArgs.TryGet to receive Init arguments at the beginning of the Awake event.\r\n    void Awake() =&gt; InitArgs.TryGet&lt;Derived, A, B&gt;(this);\r\n}<\/span><\/pre>\n<hr \/>\n<h1>Problem<\/h1>\n<p>You have a common base class that does not depend on any services.<\/p>\n<p>You want to create a several classes that derives from that base class, which depend on different services.<\/p>\n<pre><span class=\"line_wrapper\">\/\/ The base class with no dependencies\r\nnamespace MyNamespace\r\n{\r\n    public abstract class BaseBehaviour : MonoBehaviour { }\r\n}\r\n\r\n<\/span><span class=\"line_wrapper\">class Derived1 : BaseBehaviour\r\n{\r\n    \/\/ Derived types depend on some services\r\n    A a;\r\n    B b;\r\n}\r\n\r\nclass Derived2 : BaseBehaviour\r\n{\r\n   C c;\r\n   D d;\r\n}\r\n<\/span><\/pre>\n<p>Since the derived classes must derive from BaseBehaviour, they can not simultaneously derive from <code>MonoBehaviour&lt;T...&gt;<\/code>. So how can derived types be created that contain all functionality both from your custom base class and from <code>MonoBehaviour&lt;T...&gt;<\/code>?<\/p>\n<h1>Solution: Base Class Generator<\/h1>\n<p>You can use a <strong>Base Class Generator<\/strong> to generate new custom base classes similar to <code>MonoBehaviour&lt;T...&gt;<\/code>, but based on your own base type.<\/p>\n<p>To create a new base class generator for your type, perform the following steps:<\/p>\n<ol>\n<li>Select <code>Create &gt; Init(args) &gt; Base Class Generator<\/code> in the Project window.<\/li>\n<li>Add the namespace that contains your base class to the Using Statements list.<\/li>\n<li>Add the desired name for the generated base classes to the <strong>Class Name<\/strong> field.<\/li>\n<li>Add the type name of your base type to the <strong>Derives From<\/strong> field.<\/li>\n<li>Click <strong>Generate<\/strong> to generate your base classes.<\/li>\n<\/ol>\n<p><img loading=\"lazy\" class=\"alignnone size-full wp-image-1109\" src=\"https:\/\/docs.sisus.co\/init-args\/wp-content\/uploads\/sites\/6\/2024\/12\/custom-base-class-generator.png\" alt=\"\" width=\"403\" height=\"284\" srcset=\"https:\/\/docs.sisus.co\/init-args\/wp-content\/uploads\/sites\/6\/2024\/12\/custom-base-class-generator.png 403w, https:\/\/docs.sisus.co\/init-args\/wp-content\/uploads\/sites\/6\/2024\/12\/custom-base-class-generator-300x211.png 300w\" sizes=\"(max-width: 403px) 100vw, 403px\" \/><\/p>\n<p>After this your types can derive from one the generated generic base types, just like they would from <code>MonoBehaviour&lt;T...&gt;<\/code>.<\/p>\n<pre class=\"code_syntax\"><span class=\"line_wrapper\">public class Derived1 : BaseBehaviour&lt;A, B&gt;\r\n<\/span><span class=\"line_wrapper\">{\r\n    A a; B b;\r\n\r\n    protected override void Init(A a, B b)\r\n    {\r\n        this.a = a;\r\n        this.b = b;\r\n    }\r\n}<\/span><\/pre>\n<p>If your base class also does have some dependencies, but only to <a href=\"https:\/\/docs.sisus.co\/init-args\/reference\/global-services\/\">global services<\/a>, and you&#8217;d still want to use the Base Class Generator with it, you could make it implement <code>IInitializable&lt;T...&gt;<\/code> and then have it automatically resolve its own dependencies during its Awake event.<\/p>\n<pre><span class=\"line_wrapper\">\/\/ The base class with no dependencies\r\nnamespace MyNamespace\r\n{\r\n    public abstract class BaseBehaviour : MonoBehaviour, IInitializable&lt;ILogger&gt;\r\n    {\r\n        ILogger logger;\r\n\r\n        public void Init(ILogger logger) =&gt; this.logger = logger;\r\n\r\n        protected virtual void Awake() =&gt; InitArgs.TryGet&lt;BaseBehaviour, ILogger&gt;(this);\r\n    }\r\n}<\/span><\/pre>\n<p><span class=\"line_wrapper\"> If you do this, make sure to define the Awake method in your base class as <code>protected virtual<\/code>, so that the generated base classes can override it.<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Problem: You have a base class that depends on some services. You want to create a class that derives from that base class, which depends on some additional services on top of the ones that the base class does. class Base : MonoBehaviour&lt;A, B&gt; { \/\/ The base class depends on some services A a; ..<\/p>\n<div class=\"clear-fix\"><\/div>\n<p><a href=\"https:\/\/docs.sisus.co\/init-args\/problems-and-solutions\/inheritance-and-dependencies\/\" 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":[9],"tags":[],"_links":{"self":[{"href":"https:\/\/docs.sisus.co\/init-args\/wp-json\/wp\/v2\/posts\/570"}],"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=570"}],"version-history":[{"count":17,"href":"https:\/\/docs.sisus.co\/init-args\/wp-json\/wp\/v2\/posts\/570\/revisions"}],"predecessor-version":[{"id":1111,"href":"https:\/\/docs.sisus.co\/init-args\/wp-json\/wp\/v2\/posts\/570\/revisions\/1111"}],"wp:attachment":[{"href":"https:\/\/docs.sisus.co\/init-args\/wp-json\/wp\/v2\/media?parent=570"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/docs.sisus.co\/init-args\/wp-json\/wp\/v2\/categories?post=570"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/docs.sisus.co\/init-args\/wp-json\/wp\/v2\/tags?post=570"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}