Below is how we start building our dependency injection. In the constructor of DbMigrator we need to supply a class that implements the ILogger interface. DbMigrator does not know or care what the name of that class is. Any class will do as long as it implements the ILogger interface. In other words, DbMigrator does not care where these messages are sent. They could be to the Console, to the screen of a WPF file, to a page on a website, or to a file or to a database. This is the whole point. All we have to do is write those concrete classes when we want to add a new place to send messages to. DbMigrator does not have to be changed. It still works fine as is. Al we have done is extended functionality.
// ANY class that implements ILogger can be passed in here.
12
// DbMigrator doesn't care which class it actually is.
13
privatereadonlyILogger _logger;
14
publicDbMigrator(ILogger logger)
15
{
16
_logger = logger;
17
}
18
publicvoidMigrate()
19
{
20
_logger.LogInfo($"Migrating started at {DateTime.Now}");
21
// details of migrating the database
22
_logger.LogInfo($"Migrating ended at {DateTime.Now}");
23
}
24
}
25
classProgram
26
{
27
staticvoidMain(string[] args)
28
{
29
}
30
}
31
}
We need to write a new class that implements ILogger, and we will finish with adding code to the Main() method. We have chosen to write a class that simply sends messages to the console. We could write a FileLogger if we chose to. We will save that for the next post, Part 3.
When we see the following code below we read that as implements. It is not inheritance. We know it is not inheritance because the identifier after the colon start with an I signifying an interface, not a class.
In the Main() we need to call the method Migrate() in DbMigrator. We need to pass in an instance of ConsoleLogger. We need to pass in a concreate class (instance/object). Notice that the Intelisense shows ILogger _logger.