Dotnet Core Console Appliction Dependency Injection
App.cs
- Add App.cs file to the project
- Add a Run method to the
App.cs
file, as shown below
// This is now equivalent to Main in Program.cs
public void Run()
{
Console.WriteLine("Hello from App.cs");
}
The App.cs
class that will be used to run the application.
Program.cs
will be used to do the setup and register the IOC container, and the App.cs
will contain all of the running console application code.
appsettings.json
Add a json configuration file to the project and name it appsettings.json
- Install Nuget Package
Microsoft.Extensions.DependencyInjection
- Install Nuget Package
Microsoft.Extensions.Configuration
- Install Nuget Package
Microsoft.Extensions.Configuration.Binder
- Install Nuget Package
Microsoft.Extensions.Configuration.Json
- IMPORTANT: Open appsettings.json properties, and change
Copy To Output Directory
, toCopy if newer
orCopy always
- Add the following to
Program.cs
static void Main(string[] args)
{
var services = ConfigureServices();
var serviceProvider = services.BuildServiceProvider();
// calls the Run method in App, which is replacing Main
serviceProvider.GetService<App>().Run();
}
private static IServiceCollection ConfigureServices()
{
IServiceCollection services = new ServiceCollection();
var config = LoadConfiguration();
services.AddSingleton(config);
// required to run the application
services.AddTransient<App>();
return services;
}
public static IConfiguration LoadConfiguration()
{
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
return builder.Build();
}
This registers the appsettings.json
with the .net core Dependency Injection container, and allows us to use the configuration file for things like connection strings and logging directories.
Using Configuration In The App
- Dependency Inject the registered configuration
// in App.cs
private readonly IConfiguration _config;
public App(IConfiguration config)
{
_config = config;
}
- Add a configuration section and value to
appsettings.json
:
{
"Runtime": {
"LogOutputDirectory": "C:\\temp\\programLog.txt"
}
}
- Use this configuration in
App.cs
public void Run()
{
var logDirectory = _config.GetValue<string>("Runtime:LogOutputDirectory");
// Using serilog here, can be anything
var log = new LoggerConfiguration()
.WriteTo.Console()
.WriteTo.File(logDirectory)
.CreateLogger();
log.Information("Serilog logger information");
Console.WriteLine("Hello from App.cs");
}
Register Interfaces with Concrete Objects
- Add the files
IUser.cs
andUser.cs
to the project - In the
Program.cs
methodConfigureServices()
add:
services.AddTransient<IUser, User>();
Which makes the ConfigureServices()
look like:
private static IServiceCollection ConfigureServices()
{
IServiceCollection services = new ServiceCollection();
var config = LoadConfiguration();
services.AddSingleton(config);
services.AddTransient<IUser, User>();
services.AddTransient<App>();
return services;
}
This allows us to write our code against our interface. In order to do so, we need to "inject" the interface into our App.cs
private readonly IConfiguration _config;
private readonly IUser _user;
public App(IConfiguration config, IUser user)
{
_config = config;
_user = user;
}
...
// using the IUser
_user.TruncateName("Jerry ");
...
Conclusion
Setting up dependency injection and configuration in this manner allows us to use configuration easily throughout our Console applicaiton, as well as giving us the ability to program against interface. This helps keep our code losely coupled and testable, along with giving us the ability to extend our application easily beyond the scope of a Console application.
Code Example On Github: https://github.com/Ballcapz/Console-Application-Dependency-Injection
Back Home