咱们都知道,在 ASP.NET CORE 中经过依赖注入的方式来使用服务十分的简单,而在 Console 中,其实也只是稍微绕了个小弯子而已。无论是内置 DI 组件或者第三方的 DI 组件(如Autofac),经过 IServiceCollection 接口咱们均可以作到和应用程序的无缝链接。本文将在别给出内置组件和第三方组件(主要是Autofac)在 Console 应用程序中的依赖注入实现方式。html
// 安装 DI 组件 Install-Package Microsoft.Extensions.DependencyInjection // 安装日志输出组件 Install-Package Microsoft.Extensions.Logging.Console
public interface ICounterAppService { void Count(int loops); } public class CounterAppService : ICounterAppService { private readonly ILogger _logger; public CounterAppService(ILoggerFactory logger) { _logger = logger.CreateLogger<CounterAppService>(); } public void Count(int loops) { for (var i = 0; i < loops; i++) _logger.LogInformation($"We have got the {i} Loop"); } }
private static void Main(string[] args) { var serviceProvider = new ServiceCollection() .AddLogging() .AddSingleton<ICounterAppService, CounterAppService>() .BuildServiceProvider(); serviceProvider .GetService<ILoggerFactory>() .AddConsole(LogLevel.Debug); var logger = serviceProvider.GetService<ILoggerFactory>() .CreateLogger<Program>(); logger.LogDebug("Starting application"); var counter = serviceProvider.GetService<ICounterAppService>(); counter.Count(10); logger.LogDebug("All done!"); }
咱们手动建立 serviceProvider 的过程其实就是 ASP.NET CORE 执行 ConfigureServices 方法的过程,一样的,上述代码也展现了手动解析 Logger 实例和经过构造函数注入解析 Logger 实例的两种方式。其中 AddLogging 方法的背后代码以下所示:app
public static IServiceCollection AddLogging(this IServiceCollection services) { if (services == null) throw new ArgumentNullException("services"); services.TryAdd(ServiceDescriptor.Singleton<ILoggerFactory, LoggerFactory>()); services.TryAdd(ServiceDescriptor.Singleton(typeof (ILogger<>), typeof (Logger<>))); return services; }
笔者曾经写过在 ASP.NET CORE 使用 Autofac 组件的例子,而在 Console 中,注册流程也没有什么变化。如下是 Program 中的代码框架
private static void Main(string[] args) { var serviceCollection = new ServiceCollection(); serviceCollection.AddLogging(); var containerBuilder = new ContainerBuilder(); // 将本来注册在内置 DI 组件中的依赖迁移入 Autofac 中 containerBuilder.Populate(serviceCollection); // 也能够把 ICounterAppService 预先注入到内置 DI 中再使用 Populate 方法迁移 containerBuilder.RegisterType<CounterAppService>().As<ICounterAppService>(); var container = containerBuilder.Build(); var serviceProvider = new AutofacServiceProvider(container); serviceProvider .GetService<ILoggerFactory>() .AddConsole(LogLevel.Debug); var logger = serviceProvider.GetService<ILoggerFactory>() .CreateLogger<Program>(); logger.LogDebug("Starting!"); var counter = serviceProvider.GetService<ICounterAppService>(); counter.Count(10); logger.LogDebug("Done!"); }
同时,Autofac中也提供了诸如 RegisterAssemblyTypes 的方法用于程序集中服务的批量注入,这也是第三方容器的优点所在。ide
Using dependency injection in a .Net Core console application
ASP.NET Core Dependency Injection Deep Dive函数