<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Filippo Ceffa</title>
    <description>The latest articles on Forem by Filippo Ceffa (@filippoceffa).</description>
    <link>https://forem.com/filippoceffa</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1035163%2Fd81ce2b3-1090-4cdf-9ed8-589dc8f7a7cd.jpg</url>
      <title>Forem: Filippo Ceffa</title>
      <link>https://forem.com/filippoceffa</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/filippoceffa"/>
    <language>en</language>
    <item>
      <title>Dependency Injection for Games — Appendix: Injection Container</title>
      <dc:creator>Filippo Ceffa</dc:creator>
      <pubDate>Mon, 11 Sep 2023 11:50:22 +0000</pubDate>
      <link>https://forem.com/filippoceffa/dependency-injection-for-games-appendix-injection-container-5ebd</link>
      <guid>https://forem.com/filippoceffa/dependency-injection-for-games-appendix-injection-container-5ebd</guid>
      <description>&lt;p&gt;In the main &lt;a href="https://dev.to/filippoceffa/dependency-injection-for-games-4dhb"&gt;Dependency Injection for Games&lt;/a&gt; article, we explained how &lt;strong&gt;Dependency Injection&lt;/strong&gt; helps you organize your &lt;strong&gt;game&lt;/strong&gt; or &lt;strong&gt;game engine&lt;/strong&gt; architecture, but we did not address one inconvenient issue that affects it.&lt;/p&gt;

&lt;p&gt;In large applications, Dependency Injection requires the user to write and maintain a lot of tedious and time-consuming &lt;strong&gt;boilerplate code&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The goal of this appendix is to demonstrate how this burden can be relieved by using a &lt;strong&gt;Dependency Injection Container&lt;/strong&gt; library.&lt;/p&gt;

&lt;p&gt;We will start by defining the problem, and providing a theoretical solution. Finally, we will show how a Container solves the problem in practice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical problem
&lt;/h2&gt;

&lt;p&gt;When examining the &lt;code&gt;main()&lt;/code&gt; function in our dummy game application, we see that Dependency Injection burdens the user with two tedious tasks:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Construct systems in an appropriate order;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Manually pass dependencies to their dependent systems.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;State&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;{};&lt;/span&gt;
    &lt;span class="c1"&gt;// 1: User must construct Physics before Simulation&lt;/span&gt;
    &lt;span class="n"&gt;Physics&lt;/span&gt; &lt;span class="n"&gt;physics&lt;/span&gt;&lt;span class="p"&gt;{};&lt;/span&gt; 
    &lt;span class="n"&gt;Simulation&lt;/span&gt; &lt;span class="n"&gt;simulation&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;physics&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="n"&gt;OpenGL&lt;/span&gt; &lt;span class="n"&gt;openGL&lt;/span&gt;&lt;span class="p"&gt;{};&lt;/span&gt;
    &lt;span class="n"&gt;Rendering&lt;/span&gt; &lt;span class="n"&gt;rendering&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;openGL&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="c1"&gt;// 2: User must manually pass simulation and rendering to Loop&lt;/span&gt;
    &lt;span class="n"&gt;Loop&lt;/span&gt; &lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;simulation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rendering&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a negligible problem in our simple example, but the cost to write and modify this boilerplate code grows significantly in an application with hundreds of systems. Is there a better way than to do this work by hand?&lt;/p&gt;

&lt;h2&gt;
  
  
  Theoretical solution
&lt;/h2&gt;

&lt;p&gt;From a theoretical point of view, our problem is very clear — we are working with a &lt;strong&gt;directed acyclic graph&lt;/strong&gt;, where nodes represent systems, and edges represent dependencies:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--I8LgMMnd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mwxfhckqd6n5ey4k2d69.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I8LgMMnd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mwxfhckqd6n5ey4k2d69.jpg" alt="Image description" width="800" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This graph contains all the information to automate the two manual tasks:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Systems construction order is determined by a depth-first traversal.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Passing dependencies only requires knowing the edges of the graph.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;How can we take advantage of this knowledge in our implementation?&lt;/p&gt;

&lt;h2&gt;
  
  
  Dependency Injection Container
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Container&lt;/strong&gt; is the software that implements our theoretical solution. Let’s take an overview at how it works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The user provides the list of services (the nodes) to the Container.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Container infers the dependencies (the edges) by looking at the parameters of the system constructors.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Container constructs and destructs systems in the correct order.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Container passes dependencies to the dependent systems.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What follows is a possible API for a &lt;strong&gt;Container library&lt;/strong&gt;, written in &lt;strong&gt;C++&lt;/strong&gt;. Please, be aware that the API refers to systems as “&lt;strong&gt;components&lt;/strong&gt;”, a more common term in the context of Dependency Injection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// We register components with the ComponentSet helper class.&lt;/span&gt;
    &lt;span class="c1"&gt;// No construction happens here, and systems can be added in any order.&lt;/span&gt;
    &lt;span class="n"&gt;ComponentSet&lt;/span&gt; &lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
    &lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Loop&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Physics&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;       
    &lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Rendering&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Simulation&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;OpenGL&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Systems are constructed in correct order in Container constructor&lt;/span&gt;
    &lt;span class="n"&gt;Container&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt; 

&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// Systems are destructed in reverse order in Container destructor&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Container can also support &lt;a href="https://dev.to/filippoceffa/dependency-injection-for-games-appendix-dependency-inversion-3coc"&gt;&lt;strong&gt;Dependency Inversion&lt;/strong&gt;&lt;/a&gt;, we only need to specify which system implements an interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Rendering depends on IGraphics&lt;/span&gt;
&lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Rendering&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; 

&lt;span class="c1"&gt;// OpenGL implements IGraphics&lt;/span&gt;
&lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;OpenGL&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;implements&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IGraphics&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Integrating a Container in your application is &lt;strong&gt;non-invasive&lt;/strong&gt;— the only file that depends on the Container is &lt;code&gt;main.cpp&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;A Container is a great tool to reduce Dependency Injection boilerplate code. However, there are some drawbacks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;It is an additional dependency to maintain in your project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An invalid graph is detected at runtime instead of compile time.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the end, whether to use a Container or not is up to you — it is perfectly possible to adopt Dependency Injection without using one.&lt;/p&gt;

&lt;p&gt;You will need to evaluate how much time you waste writing and modifying boilerplate code, and decide if using a Container is worth the tradeoff.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next steps
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If you wish to check out the &lt;strong&gt;implementation&lt;/strong&gt; of the dummy game application using a Container, or are curious about the theory and implementation of a &lt;strong&gt;C++ Container library&lt;/strong&gt;, please refer to the accompanying &lt;a href="https://github.com/Ceffa93/dependency_injection_for_games"&gt;&lt;strong&gt;GitHub repository&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you haven’t yet, read the appendix on &lt;a href="https://dev.to/filippoceffa/dependency-injection-for-games-appendix-dependency-inversion-3coc"&gt;&lt;strong&gt;Dependency Inversion&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>gamedev</category>
      <category>architecture</category>
      <category>cpp</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Dependency Injection for Games — Appendix: Dependency Inversion</title>
      <dc:creator>Filippo Ceffa</dc:creator>
      <pubDate>Mon, 11 Sep 2023 11:50:11 +0000</pubDate>
      <link>https://forem.com/filippoceffa/dependency-injection-for-games-appendix-dependency-inversion-3coc</link>
      <guid>https://forem.com/filippoceffa/dependency-injection-for-games-appendix-dependency-inversion-3coc</guid>
      <description>&lt;p&gt;In the main &lt;a href="https://dev.to/filippoceffa/dependency-injection-for-games-4dhb"&gt;Dependency Injection for Games&lt;/a&gt; article, we used a dummy game application as an example to explain how &lt;strong&gt;Dependency Injection&lt;/strong&gt; can help you organize your &lt;strong&gt;game&lt;/strong&gt; or &lt;strong&gt;game engine&lt;/strong&gt; architecture.&lt;/p&gt;

&lt;p&gt;For the sake of simplicity, the example intentionally omitted a technique commonly adopted in real-world applications: &lt;strong&gt;Dependency Inversion&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The goal of this appendix is to expand our problem to include Dependency Inversion, and prove that Dependency Injection remains the ideal solution.&lt;/p&gt;

&lt;p&gt;We will start by introducing Dependency Inversion through a &lt;strong&gt;practical example&lt;/strong&gt;, by modifying our dummy game application to make use of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem (re)definition
&lt;/h2&gt;

&lt;p&gt;First, let’s recap the dependency graph of our dummy game application:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7uE5jjZD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zht9t50o6clxldhvhq1u.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7uE5jjZD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zht9t50o6clxldhvhq1u.jpg" alt="Image description" width="800" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Rendering uses the &lt;code&gt;OpenGL&lt;/code&gt; graphics API, but as the requirements of our project grow, we may want &lt;code&gt;Rendering&lt;/code&gt; to work with multiple graphics APIs. The following scenarios are common:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We wish &lt;code&gt;Rendering&lt;/code&gt; to support both &lt;code&gt;Vulkan&lt;/code&gt; and &lt;code&gt;OpenGL&lt;/code&gt;, and select the appropriate API at runtime, based on a command-line argument.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We wish to test &lt;code&gt;Rendering&lt;/code&gt; using a &lt;code&gt;Mock&lt;/code&gt; graphics API, in order to make test results independent of graphics API details.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can provide this flexibility by making &lt;code&gt;Rendering&lt;/code&gt; depend on the &lt;code&gt;IGraphics&lt;/code&gt; interface, and make &lt;code&gt;OpenGL&lt;/code&gt;, &lt;code&gt;Vulkan&lt;/code&gt; and &lt;code&gt;Mock&lt;/code&gt; implement it:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--S8LLL0n8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w106jnfrfzsx118hbguh.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--S8LLL0n8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w106jnfrfzsx118hbguh.jpg" alt="Image description" width="800" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This solution follows the &lt;strong&gt;Dependency Inversion&lt;/strong&gt; principle, which states that systems should depend on interfaces instead of implementations:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Rdf1NuHC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r22oq2o1jkbw28u6b19p.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Rdf1NuHC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r22oq2o1jkbw28u6b19p.jpg" alt="Image description" width="800" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The introduction of Dependency Inversion slightly changes the nature of our problem — we are not dealing anymore with a dependency graph of systems, but with a &lt;strong&gt;dependency graph of systems and interfaces&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In the next section we will see how Dependency Injection comfortably supports these new requirements, and remains the ideal solution to organize your game architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem solution
&lt;/h2&gt;

&lt;p&gt;Dependency Inversion shields a system from the implementation details of its dependencies, including their &lt;strong&gt;constructors&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Consequently, when adopting Dependency Inversion, a system cannot be responsible for creating its own dependencies. They must be created somewhere else, and shared with the system through their interface.&lt;/p&gt;

&lt;p&gt;An application that adopts &lt;strong&gt;Dependency Injection&lt;/strong&gt; creates all systems in &lt;code&gt;main()&lt;/code&gt;, and forwards them to their dependent systems. This provides the perfect framework to support Dependency Inversion:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;OpenGL&lt;/span&gt; &lt;span class="n"&gt;openGL&lt;/span&gt;&lt;span class="p"&gt;{};&lt;/span&gt;             &lt;span class="c1"&gt;// dependency created outside system&lt;/span&gt;
    &lt;span class="n"&gt;Rendering&lt;/span&gt; &lt;span class="n"&gt;rendering&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;openGL&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="c1"&gt;// dependency passed to system&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The only step necessary to adopt Dependency Inversion is to change a system’s dependency from a concrete implementation to an interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OpenGL&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IGraphics&lt;/span&gt; &lt;span class="p"&gt;{...};&lt;/span&gt;

&lt;span class="n"&gt;Rendering&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Rendering&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OpenGL&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;){}&lt;/span&gt;    &lt;span class="c1"&gt;// Injection, but not Inversion&lt;/span&gt;
&lt;span class="n"&gt;Rendering&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Rendering&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IGraphics&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;){}&lt;/span&gt; &lt;span class="c1"&gt;// Injection and Inversion&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;Dependency Injection can effortlessly support Dependency Inversion.&lt;/p&gt;

&lt;p&gt;Dependency Inversion is a powerful tool in your toolbox — it has &lt;strong&gt;benefits&lt;/strong&gt; in modularity and testability, and it has &lt;strong&gt;drawbacks&lt;/strong&gt; in complexity and performance. Like every tool, it should be used when appropriate.&lt;/p&gt;

&lt;p&gt;Dependency Injection grants you full control in deciding if and where to adopt Dependency Inversion, allowing you to design your game or game engine architecture in complete flexibility.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next steps
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Check out the accompanying &lt;a href="https://github.com/Ceffa93/dependency_injection_for_games"&gt;&lt;strong&gt;GitHub repository&lt;/strong&gt;&lt;/a&gt;, which contains an &lt;strong&gt;implementation&lt;/strong&gt; of the dummy game application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you haven’t yet, read the appendix on &lt;a href="https://dev.to/filippoceffa/dependency-injection-for-games-appendix-injection-container-5ebd"&gt;&lt;strong&gt;Injection Container&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>gamedev</category>
      <category>architecture</category>
      <category>cpp</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Dependency Injection for Games</title>
      <dc:creator>Filippo Ceffa</dc:creator>
      <pubDate>Mon, 11 Sep 2023 11:49:59 +0000</pubDate>
      <link>https://forem.com/filippoceffa/dependency-injection-for-games-4dhb</link>
      <guid>https://forem.com/filippoceffa/dependency-injection-for-games-4dhb</guid>
      <description>&lt;p&gt;Whether you are a &lt;strong&gt;game programmer&lt;/strong&gt; or a &lt;strong&gt;game engine developer&lt;/strong&gt;, a well-organized architecture is crucial to keep your project maintainable, readable, and safe— especially if you work with a team on a large codebase.&lt;/p&gt;

&lt;p&gt;This article aims to present the concept of &lt;strong&gt;Dependency Injection&lt;/strong&gt;, and to show how it can help you to easily structure your &lt;strong&gt;game architecture&lt;/strong&gt; in a robust and flexible way, without any performance overhead.&lt;/p&gt;

&lt;p&gt;Using a dummy game application as a &lt;strong&gt;practical example&lt;/strong&gt;, we will start by defining the problem we intend to solve. We will try different strategies, and demonstrate how Dependency Injection emerges as the ideal solution.&lt;/p&gt;

&lt;p&gt;We will use &lt;strong&gt;C++&lt;/strong&gt;, the go-to language for high-performance applications, but the ideas discussed are universal, and applicable in other languages.&lt;/p&gt;

&lt;p&gt;The code presented in this article is available on &lt;a href="https://github.com/Ceffa93/dependency_injection_for_games"&gt;&lt;strong&gt;GitHub&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem Definition
&lt;/h2&gt;

&lt;p&gt;Games are complex applications, consisting of multiple unique systems, such as Rendering or Physics. In a typical game application, systems are initialized on startup, they interact with each other for the lifetime of the application, and are destroyed when the application terminates.&lt;/p&gt;

&lt;p&gt;Some systems are specific to the game being developed, while others are more general, and are typically wrapped into a &lt;strong&gt;game engine&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1liPNz6N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/69oeromapt1g1yj72j9a.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1liPNz6N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/69oeromapt1g1yj72j9a.jpg" alt="Image description" width="800" height="171"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In our discussion we will not consider this separation, and refer to any system in the application as a &lt;strong&gt;game system&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Let’s now introduce the example that will accompany us for the rest of this article — a dummy 2D game application where two red circles bounce around the screen. Our game consists of just a handful of systems:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--m954nEyH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fjc5gds55wsdo6q55dpt.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--m954nEyH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fjc5gds55wsdo6q55dpt.jpg" alt="Image description" width="800" height="76"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;State&lt;/code&gt; holds the state of the game: the circle positions and velocities.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Simulation&lt;/code&gt; moves circles in the &lt;code&gt;update()&lt;/code&gt; method, modifying &lt;code&gt;State&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Physics&lt;/code&gt; is used by &lt;code&gt;Simulation&lt;/code&gt; in &lt;code&gt;update()&lt;/code&gt; to resolve circle collisions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Rendering&lt;/code&gt; reads &lt;code&gt;State&lt;/code&gt;, and draws circles on screen with &lt;code&gt;render()&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;OpenGL&lt;/code&gt; wraps the OpenGL API, required by &lt;code&gt;Rendering&lt;/code&gt; to &lt;code&gt;render()&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Loop&lt;/code&gt; runs the game loop, which calls &lt;code&gt;update()&lt;/code&gt; and then &lt;code&gt;render()&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s identify the &lt;strong&gt;dependencies&lt;/strong&gt; between our systems:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--m8oyXBAt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3rgilpclp6cfjzvluzl6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--m8oyXBAt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3rgilpclp6cfjzvluzl6.jpg" alt="Image description" width="800" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The design of our application is nicely represented by a graph, where nodes represent systems, and edges represent dependencies. In particular, this is a &lt;strong&gt;directed acyclic graph&lt;/strong&gt;, where there is no circular dependency.&lt;/p&gt;

&lt;p&gt;Now that we have a solid theoretical understanding of how to organize our architecture, it is time to introduce the concrete problem at the core of this article: &lt;strong&gt;how do we turn this theory into practice?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We wish to find a way to &lt;strong&gt;accurately&lt;/strong&gt; express our theoretical architecture in code, with a focus on &lt;strong&gt;clarity&lt;/strong&gt;, &lt;strong&gt;safety&lt;/strong&gt;, &lt;strong&gt;modularity&lt;/strong&gt; and &lt;strong&gt;performance&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of trying to derive our solution from these high-level goals, in the next section we will proceed bottom-up, and &lt;strong&gt;dive into implementation&lt;/strong&gt;. As we try different strategies, we will get a practical understanding of what problems we wish to avoid, and we will define rules that we wish to follow.&lt;/p&gt;

&lt;p&gt;Eventually, we will converge on an ideal solution: &lt;strong&gt;Dependency Injection&lt;/strong&gt;.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;Further reading:&lt;br&gt;
For simplicity, we ignore the situation where systems implement and depend on interfaces, quite common in real game applications. If you are interested to know more, refer to the appendix on &lt;a href="https://dev.to/filippoceffa/dependency-injection-for-games-appendix-dependency-inversion-3coc"&gt;&lt;strong&gt;Dependency Inversion&lt;/strong&gt;&lt;/a&gt; after finishing this article.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Problem Solution
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Attempt 1: Systems are global variables
&lt;/h3&gt;

&lt;p&gt;Based on the problem definition, we know that game systems must be unique, created at startup, and destroyed at shutdown. These requirements are satisfied by creating a global variable for each system:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// State.h&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;State&lt;/span&gt;&lt;span class="p"&gt;{...};&lt;/span&gt;     &lt;span class="c1"&gt;// class definition&lt;/span&gt;
&lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt; &lt;span class="n"&gt;g_state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// global variable declaration&lt;/span&gt;

&lt;span class="c1"&gt;// State.cpp&lt;/span&gt;
&lt;span class="n"&gt;State&lt;/span&gt; &lt;span class="n"&gt;g_state&lt;/span&gt;&lt;span class="p"&gt;{};&lt;/span&gt;      &lt;span class="c1"&gt;// global variable definition&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Systems access dependencies directly from global state:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;State.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Simulation&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Simulation&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;g_state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One problem with global variables is that we do not control their construction order. If &lt;code&gt;g_simulation&lt;/code&gt; happens to be constructed before &lt;code&gt;g_state&lt;/code&gt;, the above code causes an uninitialized memory access.&lt;/p&gt;

&lt;p&gt;We wish to have a way to guarantee that &lt;code&gt;g_simulation&lt;/code&gt; is constructed after &lt;code&gt;g_state&lt;/code&gt;. And, to avoid the same issue in the destructor, we also wish to guarantee that &lt;code&gt;g_simulation&lt;/code&gt; is destroyed before &lt;code&gt;g_state&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let’s formalize our wish in a rule:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Rule 1: Systems must be created after / destroyed before dependencies.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Another problem with global variables is that their access is not limited to constructors — they can be accessed from anywhere:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Simulation&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="n"&gt;g_state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This freedom has a side effect — it becomes difficult to understand the dependencies of a system, because they are not listed in a single place.&lt;/p&gt;

&lt;p&gt;Unclear dependencies make it hard to understand the architecture, to refactor, and to make changes. Let’s define a rule to prevent this situation:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Rule 2: Dependencies must be explicit.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The final issue with global variables is the potential to easily introduce &lt;strong&gt;circular dependencies&lt;/strong&gt; between systems:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Physics&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;g_rendering&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Rendering&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;g_physics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To ensure that our codebase remains &lt;strong&gt;modular&lt;/strong&gt; and &lt;strong&gt;maintainable&lt;/strong&gt;, we wish to forbid circular dependencies altogether:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Rule 3: Introducing circular dependencies must be prevented.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Attempt 2: Systems own dependencies
&lt;/h3&gt;

&lt;p&gt;Let’s make systems responsible for managing their own dependencies. &lt;br&gt;
The dependencies are member variables, created in the constructor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt; &lt;span class="n"&gt;Loop&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Loop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
 &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;m_simulation&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="c1"&gt;// dependency created here&lt;/span&gt;
 &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;m_rendering&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
 &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="n"&gt;Loop&lt;/span&gt;&lt;span class="o"&gt;::~&lt;/span&gt;&lt;span class="n"&gt;Loop&lt;/span&gt;&lt;span class="p"&gt;(){}&lt;/span&gt; &lt;span class="c1"&gt;// dependency destroyed here&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using constructor recursion, a system creates its entire dependency subgraph. Consequently, constructing the root system &lt;code&gt;Loop&lt;/code&gt; triggers the creation of every system.&lt;/p&gt;

&lt;p&gt;We construct our application by creating &lt;code&gt;Loop&lt;/code&gt; on the stack of &lt;code&gt;main()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
 &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="n"&gt;Loop&lt;/span&gt; &lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;{};&lt;/span&gt; &lt;span class="c1"&gt;// recursively construct every system&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A problem arises when multiple systems, like &lt;code&gt;Simulation&lt;/code&gt; and &lt;code&gt;Rendering&lt;/code&gt;, depend on the same system, such as &lt;code&gt;State&lt;/code&gt;. Both &lt;code&gt;Simulation&lt;/code&gt; and &lt;code&gt;Rendering&lt;/code&gt; create separate copies of &lt;code&gt;State&lt;/code&gt;, but systems must be &lt;strong&gt;unique&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;To resolve this, we can create &lt;code&gt;State&lt;/code&gt; within &lt;code&gt;Loop&lt;/code&gt;, the parent system of &lt;code&gt;Simulation&lt;/code&gt; and &lt;code&gt;Rendering&lt;/code&gt;, and have &lt;code&gt;Loop&lt;/code&gt; share &lt;code&gt;State&lt;/code&gt; with their constructors by reference:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt; &lt;span class="n"&gt;Loop&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Loop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
 &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;m_state&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="c1"&gt;// create here&lt;/span&gt;
 &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;m_simulation&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;m_state&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// share reference&lt;/span&gt;
 &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;m_rendering&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;m_state&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// share reference&lt;/span&gt;
 &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This solution patches the problem, but it introduces an extra dependency. We have failed to exactly map our theoretical architecture into code:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2LE8KrMT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kf1c5vj2yv30lr697we5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2LE8KrMT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kf1c5vj2yv30lr697we5.jpg" alt="Image description" width="800" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There is a fundamental problem with this approach that prevents us from converging on an ideal solution. In order to understand it, we should take a step back, and start thinking in terms of &lt;strong&gt;responsibilities.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Systems are burdened with &lt;strong&gt;two&lt;/strong&gt; responsibilities:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Functionality:&lt;/strong&gt; executing the logic that defines system behavior.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Structure&lt;/strong&gt;: creating, destroying, organizing, passing dependencies.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The dependency graph should only reflect dependencies that occur due to &lt;strong&gt;functionality&lt;/strong&gt;, such as &lt;code&gt;Simulation&lt;/code&gt; depending on &lt;code&gt;Physics&lt;/code&gt; for collision resolution. However, the need for organizing the application &lt;strong&gt;structure&lt;/strong&gt; introduces additional dependencies, such as &lt;code&gt;Loop&lt;/code&gt; depending on &lt;code&gt;State&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To resolve this problem, we wish to follow the &lt;strong&gt;single responsibility principle&lt;/strong&gt;, and give systems a single responsibility: &lt;strong&gt;functionality&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Rule 4: Systems must not be responsible to structure the application.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Successful attempt: Systems receive dependencies
&lt;/h3&gt;

&lt;p&gt;In this final attempt, the responsibility for structuring the application is moved to &lt;code&gt;main()&lt;/code&gt;, where every system is created in the correct order, and passed as dependency to other systems:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
 &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="n"&gt;State&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;{};&lt;/span&gt;
     &lt;span class="n"&gt;Physics&lt;/span&gt; &lt;span class="n"&gt;physics&lt;/span&gt;&lt;span class="p"&gt;{};&lt;/span&gt;
     &lt;span class="n"&gt;Simulation&lt;/span&gt; &lt;span class="n"&gt;simulation&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;physics&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
     &lt;span class="n"&gt;OpenGL&lt;/span&gt; &lt;span class="n"&gt;openGL&lt;/span&gt;&lt;span class="p"&gt;{};&lt;/span&gt;
     &lt;span class="n"&gt;Rendering&lt;/span&gt; &lt;span class="n"&gt;rendering&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;openGL&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
     &lt;span class="n"&gt;Loop&lt;/span&gt; &lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;simulation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rendering&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;  
 &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// out of scope: system destructed in reverse order&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Systems are no longer responsible for structuring the application. They receive their dependencies through the &lt;strong&gt;constructor&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt; &lt;span class="n"&gt;Loop&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Loop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Simulation&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;simulationRef&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Rendering&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;renderingRef&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;m_simulationRef&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;simulationRef&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;m_renderingRef&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;renderingRef&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach follows all our rules:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Rule 1: Systems must be created after / destroyed before dependencies.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;✅ System is outlived by its dependency, as it is created later on the stack.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Rule 2: Dependencies must be explicit.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;✅ The signature of the system constructor lists all dependencies.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Rule 3: Introducing circular dependencies must be prevented.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;✅ It is impossible to order system creation to cause a cycle.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Rule 4: Systems must not be responsible to structure the application.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;✅ Application structure is entirely determined in main().&lt;/p&gt;

&lt;p&gt;Success!&lt;/p&gt;

&lt;p&gt;We converged on a solution that precisely implements our theoretical architecture, while being simple, safe, modular and efficient.&lt;/p&gt;

&lt;p&gt;As promised, this ideal solution is none other than an implementation of &lt;strong&gt;Dependency Injection&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Dependency Injection is a programming technique in which an object [..] receives other objects [..] that it depends on.&lt;br&gt;
(Wikipedia)&lt;/p&gt;
&lt;/blockquote&gt;




&lt;blockquote&gt;
&lt;p&gt;Further reading:&lt;br&gt;
In applications with a large number of systems, the cost to write and modify the code in &lt;code&gt;main()&lt;/code&gt; is significant. If you wish to learn of an automated solution to reduce the boilerplate code, refer to the appendix on &lt;a href="https://dev.to/filippoceffa/dependency-injection-for-games-appendix-injection-container-5ebd"&gt;&lt;strong&gt;Injection Container&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;I hope this article was able to make you excited about Dependency Injection, and its application in game development.&lt;/p&gt;

&lt;p&gt;By adopting Dependency Injection, you will quickly realize how radically it improves your everyday game development experience:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You will easily understand, reason and discuss your architecture.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You will quickly refactor and make changes with peace of mind.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You will never worry about accessing uninitialized dependencies.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I suggest that you try adopting Dependency Injection in your own project, and I believe you will not be able to look back!&lt;/p&gt;

&lt;h2&gt;
  
  
  Next steps
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Check out the accompanying &lt;a href="https://github.com/Ceffa93/dependency_injection_for_games"&gt;&lt;strong&gt;GitHub repository&lt;/strong&gt;&lt;/a&gt;, which contains an &lt;strong&gt;implementation&lt;/strong&gt; of the dummy game application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Read the appendices on &lt;a href="https://dev.to/filippoceffa/dependency-injection-for-games-appendix-dependency-inversion-3coc"&gt;&lt;strong&gt;Dependency Inversion&lt;/strong&gt;&lt;/a&gt; and &lt;a href="https://dev.to/filippoceffa/dependency-injection-for-games-appendix-injection-container-5ebd"&gt;&lt;strong&gt;Injection Container&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you have any questions, or wish to share your thoughts, please feel free to leave a &lt;strong&gt;comment&lt;/strong&gt;, or to contact me on &lt;a href="https://www.linkedin.com/in/filippoceffa/"&gt;&lt;strong&gt;LinkedIn&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>gamedev</category>
      <category>architecture</category>
      <category>cpp</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
