-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdependency-injection-intro.html
154 lines (118 loc) · 9.62 KB
/
dependency-injection-intro.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
<!DOCTYPE html>
<html lang="en"><head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1"><!-- Begin Jekyll SEO tag v2.8.0 -->
<title>Dependency Injection | Kostas Konstantopoulos</title>
<meta name="generator" content="Jekyll v4.1.1" />
<meta property="og:title" content="Dependency Injection" />
<meta property="og:locale" content="en_US" />
<link rel="canonical" href="http://localhost:4000/dependency-injection-intro" />
<meta property="og:url" content="http://localhost:4000/dependency-injection-intro" />
<meta property="og:site_name" content="Kostas Konstantopoulos" />
<meta property="og:type" content="article" />
<meta property="article:published_time" content="2021-04-08T16:36:00+02:00" />
<meta name="twitter:card" content="summary" />
<meta property="twitter:title" content="Dependency Injection" />
<script type="application/ld+json">
{"@context":"https://schema.org","@type":"BlogPosting","dateModified":"2021-04-08T16:36:00+02:00","datePublished":"2021-04-08T16:36:00+02:00","headline":"Dependency Injection","mainEntityOfPage":{"@type":"WebPage","@id":"http://localhost:4000/dependency-injection-intro"},"url":"http://localhost:4000/dependency-injection-intro"}</script>
<!-- End Jekyll SEO tag -->
<link rel="stylesheet" href="/assets/main.css"><link type="application/atom+xml" rel="alternate" href="http://localhost:4000/feed.xml" title="Kostas Konstantopoulos" /></head>
<body><header class="site-header" role="banner">
<div class="wrapper"><a class="site-title" rel="author" href="/">Kostas Konstantopoulos</a><nav class="site-nav">
<input type="checkbox" id="nav-trigger" class="nav-trigger" />
<label for="nav-trigger">
<span class="menu-icon">
<svg viewBox="0 0 18 15" width="18px" height="15px">
<path d="M18,1.484c0,0.82-0.665,1.484-1.484,1.484H1.484C0.665,2.969,0,2.304,0,1.484l0,0C0,0.665,0.665,0,1.484,0 h15.032C17.335,0,18,0.665,18,1.484L18,1.484z M18,7.516C18,8.335,17.335,9,16.516,9H1.484C0.665,9,0,8.335,0,7.516l0,0 c0-0.82,0.665-1.484,1.484-1.484h15.032C17.335,6.031,18,6.696,18,7.516L18,7.516z M18,13.516C18,14.335,17.335,15,16.516,15H1.484 C0.665,15,0,14.335,0,13.516l0,0c0-0.82,0.665-1.483,1.484-1.483h15.032C17.335,12.031,18,12.695,18,13.516L18,13.516z"/>
</svg>
</span>
</label>
<div class="trigger"></div>
</nav></div>
</header>
<main class="page-content" aria-label="Content">
<div class="wrapper">
<article class="post h-entry" itemscope itemtype="http://schema.org/BlogPosting">
<header class="post-header">
<h1 class="post-title p-name" itemprop="name headline">Dependency Injection</h1>
<p class="post-meta">
<time class="dt-published" datetime="2021-04-08T16:36:00+02:00" itemprop="datePublished">Apr 8, 2021
</time></p>
</header>
<div class="post-content e-content" itemprop="articleBody">
<p>Dependency injection is the act of passing resources (“dependencies”) from an outer scope to an inner one, instead of letting the inner scope accessing them directly.</p>
<p>The most common way to “inject” the resources is to pass them as function arguments. In the extreme case even simple function primitive arguments can be considered as a form on dependency injection, but the term is usually reserved for more complex components.</p>
<p>Common reasons behind this concept:</p>
<ul>
<li><a href="/functional-purity">Functional purity</a>.</li>
<li>Remove irrelevant responsibilities from inner scopes.</li>
<li><a href="/strategy-factory-pattern">Strategy pattern</a>.</li>
<li>Ability re-use same resource instance and centrally regulate access to it.</li>
</ul>
<p>The common denominator is the need to dynamically select the dependency instance at runtime.</p>
<p>Example: Function <em>get_season_today</em> returns the season of the year based on today’s date (eg. “spring”).</p>
<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="c1">#!/usr/bin/python
</span>
<span class="kn">import</span> <span class="nn">datetime</span>
<span class="k">def</span> <span class="nf">get_season_today</span><span class="p">()</span> <span class="o">-></span> <span class="nb">str</span><span class="p">:</span>
<span class="s">"""
Finds what the current season is based on today's date.
:return: The name of the season.
"""</span>
<span class="n">month</span> <span class="o">=</span> <span class="n">datetime</span><span class="p">.</span><span class="n">date</span><span class="p">.</span><span class="n">today</span><span class="p">().</span><span class="n">month</span>
<span class="k">if</span> <span class="mi">3</span> <span class="o"><=</span> <span class="n">month</span> <span class="o"><=</span> <span class="mi">5</span><span class="p">:</span>
<span class="k">return</span> <span class="s">"spring"</span>
<span class="k">if</span> <span class="mi">6</span> <span class="o"><=</span> <span class="n">month</span> <span class="o"><=</span> <span class="mi">8</span><span class="p">:</span>
<span class="k">return</span> <span class="s">"summer"</span>
<span class="k">if</span> <span class="mi">9</span> <span class="o"><=</span> <span class="n">month</span> <span class="o"><=</span> <span class="mi">11</span><span class="p">:</span>
<span class="k">return</span> <span class="s">"autumn"</span>
<span class="k">return</span> <span class="s">"winter"</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
<span class="k">print</span><span class="p">(</span><span class="n">get_season_today</span><span class="p">())</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">"__main__"</span><span class="p">:</span>
<span class="n">main</span><span class="p">()</span></code></pre></figure>
<p>Today’s datetime resource is retrieved from within the function itself. Notice how this makes <em>get_season_today</em> function impure and hard to test (it is hard to control the system’s date). On top of that, this code is not reusable. What if we wanted to know the season 27 days from today? We would have to define a new function (called something like <em>get_season_after_27_days</em>) with a lot of duplicate code.</p>
<p>This is definitely not the way to go!</p>
<p>The solution in this case is simple: Inject the datetime resource from an outer scope!</p>
<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="c1">#!/usr/bin/python
</span>
<span class="kn">import</span> <span class="nn">datetime</span>
<span class="k">def</span> <span class="nf">get_season_today</span><span class="p">(</span><span class="n">today</span><span class="p">:</span> <span class="n">datetime</span><span class="p">)</span> <span class="o">-></span> <span class="nb">str</span><span class="p">:</span>
<span class="s">"""
Finds what the current season is based on today's date.
:param today: Today's date.
:return: The name of the season.
"""</span>
<span class="n">month</span> <span class="o">=</span> <span class="n">today</span><span class="p">.</span><span class="n">month</span>
<span class="k">if</span> <span class="mi">3</span> <span class="o"><=</span> <span class="n">month</span> <span class="o"><=</span> <span class="mi">5</span><span class="p">:</span>
<span class="k">return</span> <span class="s">"spring"</span>
<span class="k">if</span> <span class="mi">6</span> <span class="o"><=</span> <span class="n">month</span> <span class="o"><=</span> <span class="mi">8</span><span class="p">:</span>
<span class="k">return</span> <span class="s">"summer"</span>
<span class="k">if</span> <span class="mi">9</span> <span class="o"><=</span> <span class="n">month</span> <span class="o"><=</span> <span class="mi">11</span><span class="p">:</span>
<span class="k">return</span> <span class="s">"autumn"</span>
<span class="k">return</span> <span class="s">"winter"</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
<span class="k">print</span><span class="p">(</span><span class="n">get_season_today</span><span class="p">(</span><span class="n">today</span><span class="o">=</span><span class="n">datetime</span><span class="p">.</span><span class="n">date</span><span class="p">.</span><span class="n">today</span><span class="p">()))</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">"__main__"</span><span class="p">:</span>
<span class="n">main</span><span class="p">()</span></code></pre></figure>
</div><a class="u-url" href="/dependency-injection-intro" hidden></a>
</article>
</div>
</main><footer class="site-footer h-card">
<data class="u-url" href="/"></data>
<div class="wrapper">
<div class="social-links"><ul class="social-media-list">
<!---->
<!---->
<!----><li><a href="https://github.com/kdop"><svg class="svg-icon"><use xlink:href="/assets/minima-social-icons.svg#github"></use></svg> <span class="username">kdop</span></a></li><!----><li><a href="https://www.linkedin.com/in/ntopoulos"><svg class="svg-icon"><use xlink:href="/assets/minima-social-icons.svg#linkedin"></use></svg> <span class="username">ntopoulos</span></a></li><!---->
<!---->
<!--<li><a href="https://www.twitter.com/ntopoulos"><svg class="svg-icon"><use xlink:href="/assets/minima-social-icons.svg#twitter"></use></svg> <span class="username">ntopoulos</span></a></li>-->
<!---->
<!---->
<!---->
</ul></div>
</div>
</footer>
</body>
</html>