.NET Core DI và các lớp con
Mới với .NET Core tại đây. Tôi đã tìm kiếm một tài liệu, chuỗi hoặc hướng dẫn khác trả lời các câu hỏi của tôi nhưng không thể tìm thấy tài liệu, nếu bạn nghĩ là có, vui lòng chỉ ra.
Tôi đang cố gắng tạo một ứng dụng bảng điều khiển .NET 5 đơn giản với DI và thực sự gặp khó khăn trong việc cấu trúc các lớp bằng ghi nhật ký.
Đây có phải là cách chính xác để chuyển trong trình ghi nhật ký (hoặc bất kỳ dịch vụ nào khác) đến một lớp con sử dụng DI trong .NET Core không? Theo mã bên dưới, trong hàm tạo lớp cha của tôi, tôi lấy thêm một ILogger cho mỗi lớp con, ví dụ.
ILogger<SubClass>?public TestClass(ILogger<TestClass> log, ILogger<SubClass> subClassLog, IConfiguration config)Làm cách nào để khởi tạo trình ghi nhật ký trong proc tĩnh của tôi
StaticProc?public static async Task<bool> StaticProc()
Program.cs:
sử dụng Microsoft.Extensions.Configuration;
sử dụng Microsoft.Extensions.DependencyInjection;
sử dụng Microsoft.Extensions.Hosting;
sử dụng Microsoft.Extensions.Logging;
sử dụng Hệ thống;
sử dụng System.IO;
sử dụng System.Threading.Tasks;
không gian tên ConsoleApp1
{
chương trình lớp học
{
static async Task Main (string [] args)
{
var builder = new ConfigurationBuilder ();
BuildConfig (người xây dựng);
var host = Host.CreateDefaultBuilder ()
.ConfigureServices ((ngữ cảnh, dịch vụ) =>
{
services.AddTransient <ITestClass, TestClass> ();
services.AddTransient <ISubClass, SubClass> ();
})
.ConfigureLogging (logBuilder =>
{
logBuilder.SetMinimumLevel (LogLevel.Trace);
logBuilder.AddLog4Net ("log4net.config");
})
.Xây dựng();
var log = host.Services.GetService <ILoggerFactory> () .CreateLogger <Program> ();
log.LogInformation ($"Application Started");
var svc = ActivatorUtilities.CreateInstance<TestClass>(host.Services);
await svc.Run();
log.LogInformation($"Ứng dụng Đã kết thúc");
}
static void BuildConfig (Trình tạo IConfigurationBuilder)
{
builder.SetBasePath (Directory.GetCurrentDirectory ())
.AddJsonFile ("appsettings.json", tùy chọn: false, reloadOnChange: true)
.AddJsonFile ($ "appsettings. {Environment.GetEnosystemVariable (" ASPNETCORE_ENVIRONMENT ") ??" Development "}. Json", tùy chọn: true)
.AddEnosystemVariables ();
}
}
}
TestClass.cs:
sử dụng Microsoft.Extensions.Configuration;
sử dụng Microsoft.Extensions.Logging;
sử dụng System.Threading.Tasks;
không gian tên ConsoleApp1
{
lớp công khai TestClass: ITestClass
{
private readonly ILogger <TestClass> _log;
private readonly ILogger <SubClass> _subClassLog;
private readonly IConfiguration _config;
public TestClass (nhật ký ILogger <TestClass>, ILogger <SubClass> subClassLog, cấu hình IConfiguration)
{
_log = nhật ký;
_subClassLog = subClassLog;
_config = config;
}
public async Task Run ()
{
for (int i = 0; i <_config.GetValue <int> ("Vòng lặp"); i ++)
_log.LogDebug ("Gỡ lỗi vòng lặp {loopNumber}", i);
for (int i = 0; i <_config.GetValue <int> ("Vòng lặp"); i ++)
_log.LogInformation ("Thông tin vòng lặp {loopNumber}", i);
for (int i = 0; i <_config.GetValue <int> ("Vòng lặp"); i ++)
_log.LogWarning ("Cảnh báo vòng lặp {loopNumber}", i);
for (int i = 0; i <_config.GetValue <int> ("Vòng lặp"); i ++)
_log.LogError ("Lỗi lặp {loopNumber}", i);
for (int i = 0; i <_config.GetValue <int> ("Vòng lặp"); i ++)
_log.LogCritical ("Vòng lặp tới hạn {loopNumber}", i);
var subClass = new SubClass (_subClassLog, _config);
chờ đợi subClass.A AnotherProc ();
chờ đợi SubClass.StaticProc ();
}
}
}
SubClass.cs:
sử dụng Microsoft.Extensions.Configuration;
sử dụng Microsoft.Extensions.Logging;
sử dụng Hệ thống;
sử dụng System.Threading.Tasks;
không gian tên ConsoleApp1
{
lớp công khai SubClass: ISubClass
{
private readonly ILogger <SubClass> _log;
private readonly IConfiguration _config;
public SubClass (nhật ký ILogger <SubClass>, cấu hình IConfiguration)
{
_log = nhật ký;
_config = config;
}
công khai không đồng bộ Tác vụ AnotherProc ()
{
for (int i = 0; i <_config.GetValue <int> ("Vòng lặp"); i ++)
_log.LogDebug ("Gỡ lỗi vòng lặp {loopNumber}", i);
for (int i = 0; i <_config.GetValue <int> ("Vòng lặp"); i ++)
_log.LogInformation ("Thông tin vòng lặp {loopNumber}", i);
for (int i = 0; i <_config.GetValue <int> ("Vòng lặp"); i ++)
_log.LogWarning ("Cảnh báo vòng lặp {loopNumber}", i);
for (int i = 0; i <_config.GetValue <int> ("Vòng lặp"); i ++)
_log.LogError ("Lỗi lặp {loopNumber}", i);
for (int i = 0; i <_config.GetValue <int> ("Vòng lặp"); i ++)
_log.LogCritical ("Vòng lặp tới hạn {loopNumber}", i);
}
public static async Task <bool> StaticProc ()
{
var returnBool = true;
thử
{
ném mới Exception ("");
}
bắt (Exception ex)
{
returnBool = false;
// Không có trường hợp nào nên không có ngoại lệ _log.
// Làm thế nào để tạo ILogger độc lập?
}
trả về returnBool;
}
}
}
appsettings.json:
{
"Vòng lặp": 15
}
log4net.config:
<? xml version = "1.0" encoding = "utf-8"?>
<log4net>
<appender name = "Info" type = "log4net.Appender.RollingFileAppender">
<giá trị ngưỡng = "DEBUG" />
<param name = "File" value = "App_Data \\ Nhật ký \\ Info.log" />
<param name = "AppendToFile" value = "true" />
<maxFileSize value = "5120KB" />
<lockModel type = "log4net.Appender.FileAppender + MinimalLock" />
<maxSizeRollBackups value = "1000" />
<layout type = "log4net.Layout.PatternLayout">
<convertPattern value = "% d {yyyy-MM-dd HH: mm: ss} - [% t]% -5p% c% x -% m% n" />
</layout>
</appender>
<appender name = "Error" type = "log4net.Appender.RollingFileAppender">
<ngưỡng giá trị = "Lỗi" />
<param name = "File" value = "App_Data \\ Log \\ Error.log" />
<param name = "AppendToFile" value = "true" />
<maxFileSize value = "5120KB" />
<lockModel type = "log4net.Appender.FileAppender + MinimalLock" />
<maxSizeRollBackups value = "1000" />
<layout type = "log4net.Layout.PatternLayout">
<convertPattern value = "% d {yyyy-MM-dd HH: mm: ss} - [% t]% -5p% c% x -% m% n" />
</layout>
</appender>
<root>
<appender-ref ref = "Thông tin" />
<appender-ref ref = "Lỗi" />
</root>
</log4net>
Trả lời
Tóm lược
Bạn cũng có thể tiêm một ILoggerFactorythay vì ILogger:
public TestClass(ILoggerFactory loggerFactory, IConfiguration config)
{
// create a class logger
_log = loggerFactory.CreateLogger<TestClass>();
// and whenever you need a new instance of a special class logger use this:
_subClassLog = loggerFactory.Create<SubTestClass>();
_config = config;
}
Nhưng lưu ý rằng điều này tạo ra một phiên bản mới của ILogger. Đăng nhập lõi asp net Trong trường hợp của bạn, nếu bạn thực sự cần phương thức tĩnh với trình ghi nhật ký, hãy tạo nó chỉ khi nó đã tồn tại:
private static readonly ILogger<SubClass> _log;
private readonly IConfiguration _config;
public SubClass(ILoggerFactory loggerFactory, IConfiguration config)
{
_log = _log ??= loggerFactory.CreateLogger<SubClass>();
_config = config;
}
Nhưng tôi sẽ thích hoặc khuyên bạn nên làm điều đó mà không cần tĩnh và chỉ cần đăng ký dịch vụ dưới dạng singleton.
ví dụ 1
Tôi đã thêm một ví dụ đầy đủ ở đây: dotnet fiddle Ví dụ 1 Cũng với DI hoạt động cho các ứng dụng bảng điều khiển như đã đề cập trong các nhận xét.
Ví dụ 2
Imo bạn không nên sử dụng nó với các phương thức tĩnh. Chỉ cần xem ví dụ thứ hai của tôi ở đây dotnet fiddle Ví dụ 2