<?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>DEV Community: bothzoli</title>
    <description>The latest articles on DEV Community by bothzoli (@bothzoli).</description>
    <link>https://dev.to/bothzoli</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%2F259599%2Fde329a7e-d6d9-4090-8e55-adbb3a6db3cb.png</url>
      <title>DEV Community: bothzoli</title>
      <link>https://dev.to/bothzoli</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bothzoli"/>
    <language>en</language>
    <item>
      <title>Implementing an IoC Container in ABAP</title>
      <dc:creator>bothzoli</dc:creator>
      <pubDate>Mon, 28 Oct 2019 07:57:39 +0000</pubDate>
      <link>https://dev.to/bothzoli/implementing-an-ioc-container-in-abap-534</link>
      <guid>https://dev.to/bothzoli/implementing-an-ioc-container-in-abap-534</guid>
      <description>&lt;h2&gt;
  
  
  Preface
&lt;/h2&gt;

&lt;p&gt;The following is an article describing my adventures of creating a naive implementation of an inversion of control container using the ABAP programming language.&lt;/p&gt;

&lt;p&gt;The first part will focus on the Dependency Inversion Principle and ways of achieving loose coupling.&lt;br&gt;
The second part will demonstrate how to use the IoC container with some highlights on it inner workings.&lt;/p&gt;
&lt;h2&gt;
  
  
  Part 1 - Dependency inversion
&lt;/h2&gt;

&lt;p&gt;The key to a modular application is &lt;a href="https://en.wikipedia.org/wiki/Loose_coupling" rel="noopener noreferrer"&gt;loose coupling&lt;/a&gt;.&lt;br&gt;
Loosely coupled components usually makes changes easier potentially reducing maintenance effort while also allowing separation of concerns and isolation for unit testing.&lt;/p&gt;

&lt;p&gt;The way to achieve loose coupling in OO applications is to adhere to the &lt;a href="https://en.wikipedia.org/wiki/Dependency_inversion_principle" rel="noopener noreferrer"&gt;Dependency Inversion Principle&lt;/a&gt; (the &lt;em&gt;D&lt;/em&gt; of &lt;em&gt;&lt;a href="https://en.wikipedia.org/wiki/SOLID" rel="noopener noreferrer"&gt;SOLID&lt;/a&gt;&lt;/em&gt;).&lt;/p&gt;
&lt;h3&gt;
  
  
  Dependency Inversion Principle
&lt;/h3&gt;

&lt;p&gt;The dependency inversion principle roughly states that:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;high level components should not depend on low level components, but both should depend on abstractions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Suppose our software consists of two cooperating modules, say module &lt;em&gt;A&lt;/em&gt; and &lt;em&gt;B&lt;/em&gt;.&lt;br&gt;
If &lt;em&gt;A&lt;/em&gt; uses some functionality of &lt;em&gt;B&lt;/em&gt;, then &lt;em&gt;A&lt;/em&gt; is &lt;em&gt;dependent&lt;/em&gt; on &lt;em&gt;B&lt;/em&gt; (i.e. &lt;em&gt;B&lt;/em&gt; is a dependency of &lt;em&gt;A&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;This relation also means that functionality implemented in &lt;em&gt;B&lt;/em&gt; is abstracted away from the point of view of &lt;em&gt;A&lt;/em&gt;, thus &lt;em&gt;B&lt;/em&gt; is at a lower level of abstraction.&lt;br&gt;
Since &lt;em&gt;A&lt;/em&gt; is calling &lt;em&gt;B&lt;/em&gt; the flow of control also points in the same direction as the dependency, i.e. from &lt;em&gt;A&lt;/em&gt; to &lt;em&gt;B&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fbothzoli%2FABAP-IoC-Container%2Fmaster%2Farticle%2Fimg%2Fdependency_inversion.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fbothzoli%2FABAP-IoC-Container%2Fmaster%2Farticle%2Fimg%2Fdependency_inversion.png" alt="Dependent Modules"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To resolve this dependent state between &lt;em&gt;A&lt;/em&gt; and &lt;em&gt;B&lt;/em&gt; we can introduce an abstraction layer (e.g. an interface) between the two components to flip the direction of the dependency.&lt;/p&gt;

&lt;p&gt;By inserting the interface between the two components &lt;em&gt;A&lt;/em&gt; will now depend on &lt;em&gt;I&lt;/em&gt; (the abstraction) rather than directly on &lt;em&gt;B&lt;/em&gt; while &lt;em&gt;B&lt;/em&gt; will also depend on &lt;em&gt;I&lt;/em&gt; (implementing the interface in this case).&lt;br&gt;
The flow of control will still go from &lt;em&gt;A&lt;/em&gt; to &lt;em&gt;I&lt;/em&gt; to &lt;em&gt;B&lt;/em&gt;, however the direction of the dependency will point &lt;em&gt;against&lt;/em&gt; the flow of control in the relation of &lt;em&gt;I&lt;/em&gt; to &lt;em&gt;B&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;This way both our components will depend on an abstraction rather than the high level component depending on the low level one.&lt;br&gt;
This creates loose coupling, as we now can easily switch &lt;em&gt;B&lt;/em&gt; to a different module, as long as we adhere to the contract defined by the abstraction &lt;em&gt;I&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fbothzoli%2FABAP-IoC-Container%2Fmaster%2Farticle%2Fimg%2Fdependency_inversion_flipped.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fbothzoli%2FABAP-IoC-Container%2Fmaster%2Farticle%2Fimg%2Fdependency_inversion_flipped.png" alt="Dependent Modules with Abstraction"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Dependency injection
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Dependency_injection" rel="noopener noreferrer"&gt;Dependency injection&lt;/a&gt; is a way of putting the Dependency Inversion Principle into practice.&lt;br&gt;
In order for our software to work we need to supply &lt;em&gt;A&lt;/em&gt; with its dependency &lt;em&gt;B&lt;/em&gt; without &lt;em&gt;A&lt;/em&gt; knowing the concrete dependency.&lt;/p&gt;

&lt;p&gt;If &lt;em&gt;A&lt;/em&gt; is using &lt;em&gt;B&lt;/em&gt; via an abstraction, but it is newing up &lt;em&gt;B&lt;/em&gt; directly then the abstraction doesn't serve it's purpose, as &lt;em&gt;A&lt;/em&gt; will still be tightly coupled to &lt;em&gt;B&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;To get the dependency to &lt;em&gt;A&lt;/em&gt; we can use several techniques, which are collectively known as dependency injection.&lt;br&gt;
These (among others) could be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Constructor injection&lt;/li&gt;
&lt;li&gt;Property injection (a.k.a. Setter injection)&lt;/li&gt;
&lt;li&gt;Factories&lt;/li&gt;
&lt;li&gt;Inversion of Control containers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the examples below I will use some variation of the following classes:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fbothzoli%2FABAP-IoC-Container%2Fmaster%2Farticle%2Fimg%2Fmodules.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fbothzoli%2FABAP-IoC-Container%2Fmaster%2Farticle%2Fimg%2Fmodules.png" alt="Dependency injection"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Constructor injection
&lt;/h4&gt;

&lt;p&gt;When using constructor injection, the dependency is injected via a parameter through the constructor and stored as an attribute.&lt;br&gt;
The following code example shows this in C#.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IDependency&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;LowLevelStuff&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HighLevelModule&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;IDependency&lt;/span&gt; &lt;span class="n"&gt;_myLowLevelModule&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;HighLevelModule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IDependency&lt;/span&gt; &lt;span class="n"&gt;lowLevelModule&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;_myLowLevelModule&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lowLevelModule&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;DoSomeStuff&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"I'll do some stuff"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;_myLowLevelModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LowLevelStuff&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LowLevelModule&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IDependency&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;LowLevelStuff&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"In LowLevelModule"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AnotherLowLevelModule&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IDependency&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;LowLevelStuff&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"In AnotherLowLevelModule"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;lowLevelModule&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;LowLevelModule&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;highLevelModule&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;HighLevelModule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lowLevelModule&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;highLevelModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DoSomeStuff&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="cm"&gt;/*
This code example produces the following results:

I'll do some stuff
In LowLevelModule
*/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of the high level module creating its own dependency, it is supplied upon creation with it.&lt;/p&gt;

&lt;p&gt;Since the high level module only knows about the abstraction (note the type of the attribute and the constructor parameter), it will not be tightly coupled to the concrete implementation.&lt;/p&gt;

&lt;h4&gt;
  
  
  Property injection
&lt;/h4&gt;

&lt;p&gt;The idea of property injection is quite similar to that of the constructor injection, but instead of supplying the dependency during object creation, it can be set using a property or setter method.&lt;/p&gt;

&lt;p&gt;Reworking the above example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HighLevelModule&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;IDependency&lt;/span&gt; &lt;span class="n"&gt;_myLowLevelModule&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;IDependency&lt;/span&gt; &lt;span class="n"&gt;MyLowLevelModule&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_myLowLevelModule&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;HighLevelModule&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Use LowLevelModule by default&lt;/span&gt;
    &lt;span class="n"&gt;_myLowLevelModule&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;LowLevelModule&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;highLevelModule&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;HighLevelModule&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;highLevelModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DoSomeStuff&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;anotherLowLevelModule&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;AnotherLowLevelModule&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;highLevelModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MyLowLevelModule&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;anotherLowLevelModule&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;highLevelModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DoSomeStuff&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="cm"&gt;/*
This code example produces the following results:

I'll do some stuff
In LowLevelModule
I'll do some stuff
In AnotherLowLevelModule
*/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that the property is public so it can be changed from outside the class.&lt;/p&gt;

&lt;p&gt;It is also possible to have a baked in default dependency (as in the code above), which then can be changed during runtime using the property setter.&lt;/p&gt;

&lt;h4&gt;
  
  
  Factories
&lt;/h4&gt;

&lt;p&gt;Another solution is to have a dependency factory, that supply an abstraction and use that in the constructor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LowLevelModuleFactory&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;IDependency&lt;/span&gt; &lt;span class="nf"&gt;CreateModule&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;LowLevelModule&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HighLevelModule&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;IDependency&lt;/span&gt; &lt;span class="n"&gt;_myLowLevelModule&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;HighLevelModule&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Use LowLevelModule by default&lt;/span&gt;
    &lt;span class="n"&gt;_myLowLevelModule&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;LowLevelModuleFactory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateModule&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;highLevelModule&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;HighLevelModule&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;highLevelModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DoSomeStuff&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="cm"&gt;/*
This code example produces the following results:

I'll do some stuff
In LowLevelModule
*/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a solution somewhere between a constructor injection and a property injection.&lt;br&gt;
It is typically also possible to configure the factory which concrete implementation it should create.&lt;/p&gt;

&lt;p&gt;The advantage of using factories is that the object creation is localized inside the factory instead of being scatter throughout the application (see also &lt;a href="https://en.wikipedia.org/wiki/Factory_method_pattern" rel="noopener noreferrer"&gt;Factory Method&lt;/a&gt;).&lt;/p&gt;
&lt;h4&gt;
  
  
  Inversion of Control containers
&lt;/h4&gt;

&lt;p&gt;The idea behind Inversion of Control containers (or IoC containers for short) is to have an object that knows how to get hold of those dependencies that will be needed throughout the life of our application.&lt;/p&gt;

&lt;p&gt;We configure the IoC container upon startup telling which concrete implementations it should supply and then leave the object creation to the IoC container.&lt;br&gt;
The following example shows a way of doing it in C# using the &lt;a href="https://autofac.org/" rel="noopener noreferrer"&gt;Autofac&lt;/a&gt; NuGet Package.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;IContainer&lt;/span&gt; &lt;span class="n"&gt;Container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ContainerBuilder&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RegisterType&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;LowLevelModule&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;().&lt;/span&gt;&lt;span class="n"&gt;As&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IDependency&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
    &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RegisterType&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;HighLevelModule&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&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;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;highLevelModule&lt;/span&gt; &lt;span class="p"&gt;=&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;Resolve&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;HighLevelModule&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
    &lt;span class="n"&gt;highLevelModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DoSomeStuff&lt;/span&gt;&lt;span class="p"&gt;();&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;The container is configured to return &lt;code&gt;LowLevelModule&lt;/code&gt; instances for &lt;code&gt;IDependency&lt;/code&gt;.&lt;br&gt;
Upon creating the &lt;code&gt;HighLevelModule&lt;/code&gt; the IoC container will realize that an &lt;code&gt;IDependency&lt;/code&gt; is needed which was not supplied and supply the constructor with a &lt;code&gt;LowLevelModule&lt;/code&gt; as configured.&lt;/p&gt;
&lt;h3&gt;
  
  
  An ABAP IoC Container
&lt;/h3&gt;

&lt;p&gt;The constructor injection, property injection and factories can easily be implemented in ABAP as in any other OO language.&lt;br&gt;
However -- as far as I know -- there is currently no standard solution for an IoC container in ABAP.&lt;/p&gt;

&lt;p&gt;Since the ABAP language supports runtime type information via the &lt;a href="https://help.sap.com/doc/abapdocu_750_index_htm/7.50/en-US/abenrtti.htm" rel="noopener noreferrer"&gt;Runtime Type Services (RTTS)&lt;/a&gt; it seems possible to implement an IoC container and in the second part of this article I will describe one way of doing it.&lt;/p&gt;
&lt;h2&gt;
  
  
  Part 2 - The ABAP IoC Container
&lt;/h2&gt;

&lt;p&gt;The following class diagram shows the IoC container (click on the image to get a more detailed version).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://raw.githubusercontent.com/bothzoli/ABAP-IoC-Container/master/article/img/zcl_ioc_container_detailed.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fbothzoli%2FABAP-IoC-Container%2Fmaster%2Farticle%2Fimg%2Fzcl_ioc_container.png" alt="IoC Container class diagram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The usage examples will be taken (in a somewhat modified form) from the unit tests created for the container.&lt;br&gt;
These will use a set of objects that were defined for testing and demostration purposes.&lt;br&gt;
The following class diagram shows these classes and interfaces.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fbothzoli%2FABAP-IoC-Container%2Fmaster%2Farticle%2Fimg%2Ftest_classes.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fbothzoli%2FABAP-IoC-Container%2Fmaster%2Farticle%2Fimg%2Ftest_classes.png" alt="Test classes class diagram"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Usage
&lt;/h3&gt;

&lt;p&gt;To use the IoC container, first you must obtain an instance of it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight abap"&gt;&lt;code&gt;&lt;span class="k"&gt;DATA&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ioc_container&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;zcl_ioc_container&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;get_instance&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;Objects can be registered in two ways into the container.&lt;br&gt;
Simply by their name (&lt;code&gt;register&lt;/code&gt; method), or by an instance (&lt;code&gt;register_instance&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;register&lt;/code&gt; method will create a mapping between an interface name and a class name.&lt;br&gt;
Whenever this interface is requested from the container, it will assume that an instance of the registered class should be created.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;register&lt;/code&gt; method will also do some checks for the registered class to see wether it can be instantiated, namely:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the class is &lt;code&gt;CREATE PUBLIC&lt;/code&gt; or friends with the container&lt;/li&gt;
&lt;li&gt;If the class is instantiatable (i.e. not an abstract class)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If either of the above checks fail the register method will throw a &lt;code&gt;ZCX_IOC_CONTAINER&lt;/code&gt; exception with the text indicating the reason of the failure.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight abap"&gt;&lt;code&gt;&lt;span class="n"&gt;ioc_container&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;interface_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;`zif_ioc_b`&lt;/span&gt;
  &lt;span class="n"&gt;class_name&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;`zcl_ioc_b_subcl`&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;

&lt;span class="k"&gt;DATA&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ioc_b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ioc_container&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;`zif_ioc_b`&lt;/span&gt; &lt;span class="p"&gt;).&lt;/span&gt;

&lt;span class="n"&gt;cl_abap_unit_assert&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;assert_bound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;ioc_b&lt;/span&gt; &lt;span class="p"&gt;).&lt;/span&gt;

&lt;span class="n"&gt;cl_abap_unit_assert&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;assert_true&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nb"&gt;xsdbool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;ioc_b&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="k"&gt;INSTANCE&lt;/span&gt; &lt;span class="k"&gt;OF&lt;/span&gt; &lt;span class="n"&gt;zcl_ioc_b_subcl&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;The &lt;code&gt;register_instance&lt;/code&gt; method can be used to register an object instance for a given interface.&lt;br&gt;
If a registered instance exists for an interface name, then that instance will always be returned by the container.&lt;br&gt;
This can be used for test double injection (as seen in the below example).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight abap"&gt;&lt;code&gt;&lt;span class="k"&gt;DATA&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ioc_a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;CAST&lt;/span&gt; &lt;span class="n"&gt;zif_ioc_a&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;cl_abap_testdouble&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;`zif_ioc_a`&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;).&lt;/span&gt;

&lt;span class="n"&gt;ioc_container&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;register_instance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;interface_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;`zif_ioc_a`&lt;/span&gt;
  &lt;span class="k"&gt;instance&lt;/span&gt;       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ioc_a&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;

&lt;span class="n"&gt;cl_abap_unit_assert&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;assert_equals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;exp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ioc_a&lt;/span&gt;
  &lt;span class="n"&gt;act&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ioc_container&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;`zif_ioc_a`&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;Both &lt;code&gt;register&lt;/code&gt; and &lt;code&gt;register_instance&lt;/code&gt; have a corresponding &lt;code&gt;deregister&lt;/code&gt; and &lt;code&gt;deregister_instance&lt;/code&gt; method counterpart.&lt;br&gt;
These methods can either be called with an interface name or without it.&lt;/p&gt;

&lt;p&gt;Calling with an interface name will remove that specific mapping, while calling it without an input parameter will clear out all the registered mappings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight abap"&gt;&lt;code&gt;&lt;span class="n"&gt;ioc_container&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;deregister&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;`zif_ioc_b`&lt;/span&gt; &lt;span class="p"&gt;).&lt;/span&gt;

&lt;span class="n"&gt;cl_abap_unit_assert&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;assert_not_bound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;ioc_container&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;`zif_ioc_b`&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;

&lt;span class="n"&gt;ioc_container&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;deregister_instance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;`zif_ioc_a`&lt;/span&gt; &lt;span class="p"&gt;).&lt;/span&gt;

&lt;span class="n"&gt;cl_abap_unit_assert&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;assert_not_bound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;ioc_container&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;`zif_ioc_a`&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;The method &lt;code&gt;resolve&lt;/code&gt; is used to get an instance of a registered interface (as seen in the above examples).&lt;br&gt;
Since object creation issues are most likely already dealt with during the &lt;code&gt;register&lt;/code&gt; call, &lt;code&gt;resolve&lt;/code&gt; will not throw exceptions but simply return a &lt;code&gt;null&lt;/code&gt; object if the object creation fails for some reason.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;resolve&lt;/code&gt; method can also be called directly with class names.&lt;br&gt;
In this case no mapping is needed beforehand and the requested class will be instantiated.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight abap"&gt;&lt;code&gt;&lt;span class="k"&gt;DATA&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ioc_b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ioc_container&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;`zcl_ioc_b_subcl`&lt;/span&gt; &lt;span class="p"&gt;).&lt;/span&gt;

&lt;span class="n"&gt;cl_abap_unit_assert&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;assert_bound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;ioc_b&lt;/span&gt; &lt;span class="p"&gt;).&lt;/span&gt;

&lt;span class="n"&gt;cl_abap_unit_assert&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;assert_true&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nb"&gt;xsdbool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;ioc_b&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="k"&gt;INSTANCE&lt;/span&gt; &lt;span class="k"&gt;OF&lt;/span&gt; &lt;span class="n"&gt;zcl_ioc_b_subcl&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 see more examples of usage please check out the unit tests in the &lt;a href="https://github.com/bothzoli/ABAP-IoC-Container/blob/master/src/zcl_ioc_container.clas.testclasses.abap" rel="noopener noreferrer"&gt;corresponding source code&lt;/a&gt; file.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementation
&lt;/h3&gt;

&lt;p&gt;The mappings and registered instances are stored in hash tables, but the central part of the IoC container is the dynamic object creation done in the &lt;code&gt;resolve&lt;/code&gt; method.&lt;br&gt;
For this I have used the &lt;a href="https://help.sap.com/doc/abapdocu_750_index_htm/7.50/en-US/abenrtti.htm" rel="noopener noreferrer"&gt;Runtime Type Services (RTTS)&lt;/a&gt; which can give information about variables, types, method parameters etc. during runtime.&lt;/p&gt;

&lt;p&gt;By using the object descriptor created based on the class's name (&lt;code&gt;cl_abap_classdescr=&amp;gt;describe_by_name&lt;/code&gt;) we can get hold of the parameter list of the constructor method with all type information.&lt;br&gt;
We can then iterate through the parameters and resolve them one by one.&lt;/p&gt;

&lt;p&gt;Should an input parameter be a simple type, it can be created with an initial value.&lt;br&gt;
And should it be an interface type, it can be (recursively) resolved by the IoC container itself.&lt;/p&gt;

&lt;p&gt;The constructor parameters are collected in a parameter table which can be used with the generic &lt;a href="https://help.sap.com/doc/abapdocu_752_index_htm/7.52/en-us/abapcreate_object_para_tables.htm" rel="noopener noreferrer"&gt;object creation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The complete source code can be found &lt;a href="https://github.com/bothzoli/ABAP-IoC-Container/blob/master/src/zcl_ioc_container.clas.abap" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Personal thoughts and improvement possibilities
&lt;/h2&gt;

&lt;p&gt;This IoC container is far from being production ready.&lt;br&gt;
I have made tests with a some &lt;em&gt;"real world"&lt;/em&gt; classes as well and as far as I could tell it is quite stable, however I certainly did not do exhaustive testing.&lt;br&gt;
I am also pretty sure that there's room for improvement regarding performance.&lt;/p&gt;

&lt;p&gt;All in all, the motivation of creating this IoC container was first and foremost curiosity.&lt;br&gt;
Although as of now I have not used it in any complex application, I can see the possibility of using it instead of factory classes.&lt;/p&gt;

&lt;p&gt;Suppose my application uses a set of utility classes.&lt;br&gt;
Instead of having factories for all the utility classes, the IoC container could be used to supply the required instances.&lt;br&gt;
When doing unit/integration testing the container can be preloaded with test double instances using the &lt;code&gt;register_instance&lt;/code&gt; method for test isolation.&lt;/p&gt;

&lt;p&gt;The source code, along with the exception class, unit tests and the classes/interfaces created for the unit tests can be found in &lt;a href="https://github.com/bothzoli/ABAP-IoC-Container/tree/master/src" rel="noopener noreferrer"&gt;this GitHub repository&lt;/a&gt; (you should be able to pull the source code using &lt;a href="https://docs.abapgit.org/" rel="noopener noreferrer"&gt;abapGit&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;In case you have questions or suggestions please feel free to reach out to me or open an issue or a pull request.&lt;br&gt;
You can find me on twitter &lt;a href="https://twitter.com/bothzoli" rel="noopener noreferrer"&gt;@bothzoli&lt;/a&gt; (DM's are open).&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;I have learned a lot from the following resources about dependency injection, I gladly recommend them if you're interested in this topic.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=zHiWqnTWsn4" rel="noopener noreferrer"&gt;Uncle Bob on the SOLID principles&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.martinfowler.com/articles/injection.html" rel="noopener noreferrer"&gt;A great article by Martin Fowler on dependency injection&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://app.pluralsight.com/library/courses/using-dependency-injection-on-ramp" rel="noopener noreferrer"&gt;Jeremy Clark's Pluralsight course on dependency injection in .NET&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I have used &lt;a href="http://plantuml.com/" rel="noopener noreferrer"&gt;PlantUML&lt;/a&gt; to create the diagrams in this article.&lt;/p&gt;

</description>
      <category>ioc</category>
      <category>di</category>
      <category>abap</category>
      <category>sap</category>
    </item>
  </channel>
</rss>
