Detailed explanation of how to use dependency injection in. NET Core console program
- 2021-10-27 06:58:10
- OfStack
Background introduction
Dependency Injection: Also known as dependency injection, or DI for short. In the previous development mode, layers and classes call each other through new1 instances of each other, which has a benefit in the development process, and can clearly know which specific implementation is used. As the software becomes larger and more complex, it is no longer appropriate to hold specific implementations with each other when it is necessary to change the implementation mode or rely on some interfaces of the third-party system. In order to cope with this situation, we should adopt contract programming: we rely on each other's stipulated contracts (interfaces), not on the specific implementation. The advantage of this is that the dependence on each other becomes very simple, also known as loose coupling. As for the mapping relationship between contract and concrete implementation, it will be determined by runtime when the program starts through configuration. This will use DI.
Dependency injection (Dependency Injection) is a design principle in object-oriented programming, which can be used to reduce the coupling between codes. In. NET Core MVC
We can use the service container IServiceCollection in the ConfigureService method of the Startup. cs file to register the mapping of the interface and its implementation classes.
For example, when we need to access the Http context, we need to configure the IHttpContextAccessor interface and its implementation class HttpContextAccessor
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}
So how do we use dependency injection when we write a. NET Core console program?
Using built-in dependency injection
In. NET Core, the assembly used by the built-in dependency injection module is
Microsoft.Extensions.DependencyInjection
.
So if you want to use built-in dependency injection in your console program, you first need to use NUGET to add a
Microsoft.Extensions.DependencyInjection
A reference to the assembly.
PM> Install-Package Microsoft.Extensions.DependencyInjection
To illustrate how to use the built-in dependency injection module of. NET Core, we create the following two service interfaces.
public interface IFooService
{
void DoThing(int number);
}
public interface IBarService
{
void DoSomeRealWork();
}
Then we add two corresponding implementation classes for these two service interfaces
public class BarService : IBarService
{
private readonly IFooService _fooService;
public BarService(IFooService fooService)
{
_fooService = fooService;
}
public void DoSomeRealWork()
{
for (int i = 0; i < 10; i++)
{
_fooService.DoThing(i);
}
}
}
public class FooService : IFooService
{
private readonly ILogger<FooService> _logger;
public FooService(ILoggerFactory loggerFactory)
{
_logger = loggerFactory.CreateLogger<FooService>();
}
public void DoThing(int number)
{
_logger.LogInformation($"Doing the thing {number}");
}
}
Code interpretation
In the above implementation class code, we used the logging module built into. NET Core, so we also need to add the corresponding assembly Microsoft. Extensions. Logging. Console using NUGET
PM> Install-Package Microsoft.Extensions.Logging.Console
Finally, let's modify Program. cs with the following code
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
public class Program
{
public static void Main(string[] args)
{
//setup our DI
var serviceProvider = new ServiceCollection()
.AddLogging()
.AddSingleton<IFooService, FooService>()
.AddSingleton<IBarService, BarService>()
.BuildServiceProvider();
//configure console logging
serviceProvider
.GetService<ILoggerFactory>()
.AddConsole(LogLevel.Debug);
var logger = serviceProvider.GetService<ILoggerFactory>()
.CreateLogger<Program>();
logger.LogInformation("Starting application");
//do the actual work here
var bar = serviceProvider.GetService<IBarService>();
bar.DoSomeRealWork();
logger.LogInformation("All done!");
}
}
Code interpretation
Final effect
Run the program, we expect the log, and output it correctly
info: DIInConsoleApp.Program[0]
Start application.
info: DIInConsoleApp.FooService[0]
Doing the thing 0
info: DIInConsoleApp.FooService[0]
Doing the thing 1
info: DIInConsoleApp.FooService[0]
Doing the thing 2
info: DIInConsoleApp.FooService[0]
Doing the thing 3
info: DIInConsoleApp.FooService[0]
Doing the thing 4
info: DIInConsoleApp.FooService[0]
Doing the thing 5
info: DIInConsoleApp.FooService[0]
Doing the thing 6
info: DIInConsoleApp.FooService[0]
Doing the thing 7
info: DIInConsoleApp.FooService[0]
Doing the thing 8
info: DIInConsoleApp.FooService[0]
Doing the thing 9
info: DIInConsoleApp.Program[0]
All done!
Using third-party dependency injection
In addition to using the built-in dependency injection module, we can also directly use a number of third-party dependency injection frameworks, such as Autofac, StructureMap.
Here we use StructureMap to replace the current built-in dependency injection framework.
First, we need to add assembly references.
PM> Install-Package StructureMap.Microsoft.DependencyInjection
Then we modify the Program. cs file with the following code
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using StructureMap;
using System;
namespace DIInConsoleApp
{
class Program
{
static void Main(string[] args)
{
var services = new ServiceCollection().AddLogging();
var container = new Container();
container.Configure(config =>
{
config.Scan(_ =>
{
_.AssemblyContainingType(typeof(Program));
_.WithDefaultConventions();
});
config.Populate(services);
});
var serviceProvider = container.GetInstance<IServiceProvider>();
serviceProvider.GetService<ILoggerFactory>().AddConsole(LogLevel.Debug);
var logger = serviceProvider.GetService<ILoggerFactory>().CreateLogger<Program>();
logger.LogInformation("Start application.");
var bar = serviceProvider.GetService<IBarService>();
bar.DoSomeRealWork();
logger.LogInformation("All done!");
Console.Read();
}
}
}
Code interpretation
Final effect
Run the program, code and the previous effect 1 sample
info: DIInConsoleApp.Program[0]
Start application.
info: DIInConsoleApp.FooService[0]
Doing the thing 0
info: DIInConsoleApp.FooService[0]
Doing the thing 1
info: DIInConsoleApp.FooService[0]
Doing the thing 2
info: DIInConsoleApp.FooService[0]
Doing the thing 3
info: DIInConsoleApp.FooService[0]
Doing the thing 4
info: DIInConsoleApp.FooService[0]
Doing the thing 5
info: DIInConsoleApp.FooService[0]
Doing the thing 6
info: DIInConsoleApp.FooService[0]
Doing the thing 7
info: DIInConsoleApp.FooService[0]
Doing the thing 8
info: DIInConsoleApp.FooService[0]
Doing the thing 9
info: DIInConsoleApp.Program[0]
All done!
This source code (local download)
Summarize