c# - .Net Core 3 Serilog 的依赖注入
问题描述
我正在做一个使用 Serilog 的 Windows 服务
这对工人来说很好:
public class Worker: BackgroundService
{
private readonly ILogger<Worker> _logger;
private readonly IConfiguration _configuration;
private readonly string _connectionString;
private bool _serviceIsStarting = true;
public Worker(ILogger<Worker> logger, IConfiguration iConfig)
{
_logger = logger;
_configuration = iConfig;
_connectionString = _configuration.GetConnectionString("DestinationDatabase");
}
//....
}
我的 Program.cs 包含以下内容:
public static IHostBuilder CreateHostBuilder(string[] args)
{
return Host.CreateDefaultBuilder(args)
.UseWindowsService()
.UseSerilog((hostingContext, loggerConfiguration) => loggerConfiguration
.ReadFrom.Configuration(hostingContext.Configuration))
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<Worker>();
});
}
一切都很好,但是我想向 Worker 实例使用的自定义类注入一个记录器:
public class DataAccess
{
private readonly string _connectionString;
private readonly ILogger<DataAccess> _logger;
public DataAccess(ILogger<DataAccess> logger, string connectionString)
{
_connectionString = connectionString;
_logger = logger;
}
//.....
}
我的问题是我不知道如何在 worker 中实例化我的类 DataAccess 或这里的依赖注入。
这是我班级的[简化]版本:
using Microsoft.Extensions.Logging;
using Dapper;
public class DataAccess
{
private readonly string _connectionString;
private readonly ILogger<DataAccess> _logger;
public DataAccess(ILogger<DataAccess> logger, string connectionString)
{
_logger = logger;
_connectionString = connectionString;
}
public void SaveInspection(InspectionElm inspection)
{
using IDbConnection connection = new System.Data.SqlClient.SqlConnection(_connectionString);
connection.Open();
var p = new DynamicParameters();
p.Add("@RodNumber", inspection.RodNumber);
p.Add("@InspectionDate", Convert.ToDateTime(inspection.InspectionDate));
p.Add("@MeasurementEnd", Convert.ToDateTime(inspection.MeasurementEnd));
p.Add("@InspectionResultPass", Convert.ToBoolean(inspection.InspectionResultPass));;
connection.Execute("InsertTindasjaMasterRecord", p, commandType: CommandType.StoredProcedure);
_logger.LogInformation("Log something...");
}
public void InitMesureResultTypes()
{
using IDbConnection connection = new System.Data.SqlClient.SqlConnection(_connectionString);
connection.Open();
connection.Execute("InitMeasureResultType", null, commandType: CommandType.StoredProcedure);
_logger.LogInformation("Log something...");
}
}
解决方案
我的问题是完全混淆了依赖倒置的一般原则,并且理解我需要摆脱这样的代码:
var db = new DataAccess(_connectionString);
所以我终于意识到要让它正常工作需要做的是:
程序.cs:
public static IHostBuilder CreateHostBuilder(string[] args)
{
return Host.CreateDefaultBuilder(args)
.UseWindowsService()
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.UseSerilog((hostingContext, loggerConfiguration) => loggerConfiguration
.ReadFrom.Configuration(hostingContext.Configuration))
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<Worker>();
services.AddScoped<IDataAccess, DataAccess>();
});
}
工人.cs:
public Worker(ILogger<Worker> logger, IConfiguration iConfig, IDataAccess dataAccess)
{
_logger = logger;
_configuration = iConfig;
_dataAccess = dataAccess;
}
数据访问.cs:
public class DataAccess: IDataAccess
{
private readonly string _connectionString;
private readonly ILogger<DataAccess> _logger;
public DataAccess(ILogger<DataAccess> logger, IConfiguration iConfig)
{
_connectionString = iConfig.GetConnectionString("DestinationDatabase");
_logger = logger;
}
}
现在一切都很完美,我唯一需要研究的是在 .ConfigureServices 中使用哪种方法是正确的:
services.AddScoped<IDataAccess , DataAccess>();
或者
services.AddTransient<IDataAccess , DataAccess>();
或者
services.AddSingleton<IDataAccess , DataAccess>();
至少我现在知道 AddScoped() 可以正常工作。
推荐阅读
- python - 如何读取和替换文本文件的一列中的特定值?
- shell - 当脚本是可执行文件时 os.listdir 的问题
- laravel - 如何指定要导入的 excel 行数
- python - RuntimeError: 图表已完成,无法修改
- php - 一页不同的图片上传形式
- kubernetes - kubernetes 无法通过 pod 内部的 ip 访问其他机器
- xamarin.forms - 子菜单项出现在底栏上而不是浮出控件内
- flutter - 如何在下拉菜单上添加文字?
- flutter - 如何使用 Google Maps Flutter 默认显示地图标签
- html - 我想使用 CSS 正确设置文本的背景颜色。它没有像我预期的那样反应