咱們都知道,在 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函數