Skip to content

Commit 7f82082

Browse files
committed
[Samples] Update Dependency Injection exercises
1 parent ae81732 commit 7f82082

2 files changed

Lines changed: 92 additions & 24 deletions

File tree

LessonsSamples/LessonsSamples/Lesson6/DI-Demo/_Exercises.html

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,18 @@ <h4 id="implement-the-console-options-as-a-set-of-commands-registered-into-di-co
1515
string MenuEntry { get; }
1616
}
1717
</code></pre>
18-
<p>Build the menu by getting all the <code>ICommand</code> implementations through constructor DI. When a menu entry is picked, it will execute that command by calling the <code>Execute()</code> function.</p>
18+
<p>Build the menu by getting all the <code>ICommand</code> implementations through constructor DI.
19+
When a menu entry is picked, it will execute that command by calling the <code>Execute()</code> function.
20+
The <code>MovieConsoleApplication</code> constructor can import all <code>IConsole</code> implementations as an <code>IEnumerable&lt;IConsole&gt;</code>:</p>
21+
<pre><code> public MovieConsoleApplication(IEnumerable&lt;ICommand&gt; commands)
22+
{
23+
}
24+
</code></pre>
1925
<h4 id="create-an-abstraction-for-the-console-iconsole">2. Create an abstraction for the console: <code>IConsole</code></h4>
2026
<ol type="a">
21-
<li><p>Why would we abstract the existent static Console class through IConsole?</p>
27+
<li><p>Register in the DI Container the <code>IConsole</code> with the <code>AppConsole</code> implementation and refactor the code to use the <code>IConsole</code></p>
2228
</li>
23-
<li><p>Register in the DIC the <code>IConsole</code> with the <code>AppConsoleImplementation</code> and refactor the code to use the <code>IConsole</code></p>
29+
<li><p>What benefits can you see?</p>
2430
</li>
2531
</ol>
2632
<h4 id="integrate-the-servicelocator-into-the-app">3. Integrate the <code>ServiceLocator</code> into the app</h4>
@@ -34,34 +40,60 @@ <h4 id="rewrite-the-moviesconsolecreator">5. Rewrite the <code>MoviesConsoleCrea
3440
<li>Reimplement the <code>MoviesConsoleCreator</code> command to support the following functionality:</li>
3541
</ol>
3642
<ul>
37-
<li>read more properties of a movie one by one. They UI will present the user the name of the property that she should enter</li>
38-
<li>The Movie should have at least the following fields: <code>Title :string</code> and <code>Rating :int</code></li>
43+
<li>read more properties of a movie one by one. They UI will show to the user the name of the property that she should enter</li>
44+
<li>The Movie should have at least the following fields: <code>Title :string</code> and <code>Rating :int</code> (see <code>Movie.cs</code>)</li>
3945
<li>when all properties of a movie were read, ask the user if she wants to add a new movie</li>
4046
</ul>
4147
<p>Use the following interfaces:</p>
4248
<pre><code>interface IEntityReader
4349
{
44-
IEntityFieldsReader&lt;T&gt; BeginEntityRead&lt;T&gt;();
50+
IEntityFieldsReader&lt;TEntity&gt; BeginEntityRead&lt;TEntity&gt;();
4551
}
4652

47-
interface IEntityFieldsReader&lt;T&gt;
53+
interface IEntityFieldsReader&lt;TEntity&gt;
4854
{
4955
IEnumerable&lt;string&gt; GetFields();
5056
void SetFieldValue(string value);
51-
T GetEntity();
57+
TEntity GetEntity();
5258
}
5359

54-
interface IEntityRepository
60+
interface IEntityRepository&lt;TEntity&gt;
5561
{
56-
IEnumerable&lt;Movie&gt; GetAll();
57-
void Add(Movie movie);
62+
IEnumerable&lt;TEntity&gt; GetAll();
63+
void Add(TEntity movie);
5864
}
5965
</code></pre>
6066
<ol type="a" start="2">
6167
<li>Write unit tests that prove that the new <code>MoviesConsoleCreator</code> works</li>
6268
</ol>
6369
<h4 id="implement-ientityreader-and-ientityfieldsreader">6. Implement <code>IEntityReader</code> and <code>IEntityFieldsReader</code></h4>
64-
<p><em>Suggestion</em>: Use <em>Service Locator Pattern</em> to get and return the <code>IEntityFieldsReader&lt;T&gt;</code> implementations on the <code>IEntityReader&lt;T&gt;()</code> function.</p>
70+
<pre><code>class EntityReader : IEntityReader
71+
{
72+
public IEntityFieldsReader&lt;TEntity&gt; BeginEntityRead&lt;TEntity&gt;()
73+
{
74+
...
75+
}
76+
}
77+
78+
class MovieFieldsReader : IEntityFieldsReader&lt;Movie&gt;
79+
{
80+
public IEnumerable&lt;string&gt; GetFields()
81+
{
82+
...
83+
}
84+
85+
public void StoreFieldValue(string name, string value)
86+
{
87+
...
88+
}
89+
90+
public Movie GetEntity()
91+
{
92+
...
93+
}
94+
}
95+
</code></pre>
96+
<p><em>Suggestion</em>: Use <em>Service Locator Pattern</em> to get and return the <code>IEntityFieldsReader&lt;TEntity&gt;</code> implementations on the <code>IEntityReader&lt;TEntity&gt;()</code> function.</p>
6597
<h4 id="make-a-generic-implementation-of-ientityfieldsreadert">7. Make a generic implementation of <code>IEntityFieldsReader&lt;T&gt;</code></h4>
6698
<p>We may have a generic class that implements <code>IEntityFieldsReader&lt;T&gt;</code> for any T by using reflection. It should be registered to DI by using the open generic type.</p>
6799
<h4 id="implement-option-4.find-movies">8. Implement option <em>4. Find Movies</em></h4>

LessonsSamples/LessonsSamples/Lesson6/DI-Demo/_Exercises.md

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,21 @@ public interface ICommand
1212
}
1313
```
1414

15-
Build the menu by getting all the `ICommand` implementations through constructor DI. When a menu entry is picked, it will execute that command by calling the `Execute()` function.
15+
Build the menu by getting all the `ICommand` implementations through constructor DI.
16+
When a menu entry is picked, it will execute that command by calling the `Execute()` function.
17+
The `MovieConsoleApplication` constructor can import all `IConsole` implementations as an `IEnumerable<IConsole>`:
18+
19+
```
20+
public MovieConsoleApplication(IEnumerable<ICommand> commands)
21+
{
22+
}
23+
```
1624

1725
#### 2. Create an abstraction for the console: `IConsole`
1826

19-
a) Why would we abstract the existent static Console class through IConsole?
27+
a) Register in the DI Container the `IConsole` with the `AppConsole` implementation and refactor the code to use the `IConsole`
2028

21-
b) Register in the DIC the `IConsole` with the `AppConsoleImplementation` and refactor the code to use the `IConsole`
29+
b) What benefits can you see?
2230

2331
#### 3. Integrate the `ServiceLocator` into the app
2432

@@ -30,29 +38,29 @@ b) Register in the DIC the `IConsole` with the `AppConsoleImplementation` and re
3038
#### 5. Rewrite the `MoviesConsoleCreator`
3139

3240
a) Reimplement the `MoviesConsoleCreator` command to support the following functionality:
33-
- read more properties of a movie one by one. They UI will present the user the name of the property that she should enter
34-
- The Movie should have at least the following fields: `Title :string` and `Rating :int`
41+
- read more properties of a movie one by one. They UI will show to the user the name of the property that she should enter
42+
- The Movie should have at least the following fields: `Title :string` and `Rating :int` (see `Movie.cs`)
3543
- when all properties of a movie were read, ask the user if she wants to add a new movie
3644

3745
Use the following interfaces:
3846

3947
```
4048
interface IEntityReader
4149
{
42-
IEntityFieldsReader<T> BeginEntityRead<T>();
50+
IEntityFieldsReader<TEntity> BeginEntityRead<TEntity>();
4351
}
4452
45-
interface IEntityFieldsReader<T>
53+
interface IEntityFieldsReader<TEntity>
4654
{
4755
IEnumerable<string> GetFields();
4856
void SetFieldValue(string value);
49-
T GetEntity();
57+
TEntity GetEntity();
5058
}
5159
52-
interface IEntityRepository
60+
interface IEntityRepository<TEntity>
5361
{
54-
IEnumerable<Movie> GetAll();
55-
void Add(Movie movie);
62+
IEnumerable<TEntity> GetAll();
63+
void Add(TEntity movie);
5664
}
5765
```
5866

@@ -61,7 +69,35 @@ b) Write unit tests that prove that the new `MoviesConsoleCreator` works
6169

6270
#### 6. Implement `IEntityReader` and `IEntityFieldsReader`
6371

64-
*Suggestion*: Use *Service Locator Pattern* to get and return the `IEntityFieldsReader<T>` implementations on the `IEntityReader<T>()` function.
72+
```
73+
class EntityReader : IEntityReader
74+
{
75+
public IEntityFieldsReader<TEntity> BeginEntityRead<TEntity>()
76+
{
77+
...
78+
}
79+
}
80+
81+
class MovieFieldsReader : IEntityFieldsReader<Movie>
82+
{
83+
public IEnumerable<string> GetFields()
84+
{
85+
...
86+
}
87+
88+
public void StoreFieldValue(string name, string value)
89+
{
90+
...
91+
}
92+
93+
public Movie GetEntity()
94+
{
95+
...
96+
}
97+
}
98+
```
99+
100+
*Suggestion*: Use *Service Locator Pattern* to get and return the `IEntityFieldsReader<TEntity>` implementations on the `IEntityReader<TEntity>()` function.
65101

66102
#### 7. Make a generic implementation of `IEntityFieldsReader<T>`
67103

0 commit comments

Comments
 (0)