Net Core: ILogger in Startup Class: Encapsulate in Extension Method
Net Core: ILogger in Startup Class: Encapsulate in Extension Method
我在Net Core中写了这段日志代码,有人提到“这可以封装在扩展方法中”。这是执行此操作的更简单方法吗,在 Net Core 2.2 中以最佳方式编写它?
Startup.cs
services.AddSingleton<ILoggerFactory, LoggerFactory>();
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>));
services.AddLogging(builder => builder.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace));
好吧,可以按照AddLogging编写扩展方法的方式来完成。
public static IServiceCollection AddCustomLogging (this IServiceCollection services) {
services.AddSingleton<ILoggerFactory, LoggerFactory>();
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>));
services.AddLogging(builder => builder.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace));
}
虽然这不可能是一个纯粹的 Whosebug 问题,但我想我可以提供一个意见:
方法 ConfigureServices
的问题是您需要定义所有依赖项,对于较大的系统,这可能意味着痛苦的长配置方法,维护起来真的很难和无聊。
要解决此问题,您可以通过划分所有配置来简化启动,为此,您可以使用 C# 的 extension methods,该方法允许 "extend" a class(添加更多方法)无需修改class.
的源代码
扩展方法很简单,就拿一个静态的class用一个静态的方法:
public static class CommonServicesExtension
{
public static IServiceCollection AddCommonServices(IServiceCollection services)
{
services.AddHttpClient();
services.AddNodaDateTime();
services.AddMemoryCache();
services.AddCurrencyExchange();
// Add and configure many things
return services;
}
}
现在你可以这样使用了:
CommonServicesExtension.AddCommonServices(serviceColletion);
但这有点丑陋且难以阅读,因此,只需将 this
添加到您的扩展方法中即可:
public static IServiceCollection AddCommonServices(this IServiceCollection services)
通过此更改,您可以像 net core 一样调用您的配置!
services.AddCommonServices();
在你的配置服务中,这样,你的配置方法从
public IServiceCollection ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddTransient<IHttpContextAccessor, HttpContextAccessor>();
services.AddDbContext<CoreContext>(options => options.UseMySql(Configuration.GetConnectionString("Core")));
services.AddDbContext<CoreReadOnlyContext>(options => options.UseMySql(Configuration.GetConnectionString("CORE_READONLY")));
services.AddDbContext<StatsContext>(options =>
options.UseMySql(Configuration.GetConnectionString("Stats")));
services.AddScoped<ProfileTokenGenerator>();
services.AddTransient<MailNotificationService>();
services.AddTransient<RegisterControllerService>();
services.AddScoped<OtherClass>();
services.AddTransient<MoreTransient>();
services.AddTransient<ThingsService>();
return services;
}
到
public IServiceCollection ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddContexts();
services.AddCommonServices();
services.AddOtherServices();
return services;
}
如您所见,更加简洁易读!
创建一个静态文件,例如;
public static class StartupConfiguration
{
public static void AddMyLogging(
this IServiceCollection services)
{
services.AddSingleton<ILoggerFactory, LoggerFactory>();
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>));
services.AddLogging(builder => builder.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace));
}
}
然后在你的 Startup class:
public void ConfigureServices(
IServiceCollection services)
{
services.AddMyLogging();
}
只调用 AddLogging
扩展方法就足够了。
services.AddLogging(builder => builder.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace));
因为,如果您查看此扩展方法的实现,您会发现 ILoggerFactory
和 ILogger<>
已经应该添加到服务中。
services.TryAdd(ServiceDescriptor.Singleton<ILoggerFactory, LoggerFactory>());
services.TryAdd(ServiceDescriptor.Singleton(typeof (ILogger<>), typeof (Logger<>)));
我在Net Core中写了这段日志代码,有人提到“这可以封装在扩展方法中”。这是执行此操作的更简单方法吗,在 Net Core 2.2 中以最佳方式编写它?
Startup.cs
services.AddSingleton<ILoggerFactory, LoggerFactory>();
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>));
services.AddLogging(builder => builder.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace));
好吧,可以按照AddLogging编写扩展方法的方式来完成。
public static IServiceCollection AddCustomLogging (this IServiceCollection services) {
services.AddSingleton<ILoggerFactory, LoggerFactory>();
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>));
services.AddLogging(builder => builder.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace));
}
虽然这不可能是一个纯粹的 Whosebug 问题,但我想我可以提供一个意见:
方法 ConfigureServices
的问题是您需要定义所有依赖项,对于较大的系统,这可能意味着痛苦的长配置方法,维护起来真的很难和无聊。
要解决此问题,您可以通过划分所有配置来简化启动,为此,您可以使用 C# 的 extension methods,该方法允许 "extend" a class(添加更多方法)无需修改class.
的源代码扩展方法很简单,就拿一个静态的class用一个静态的方法:
public static class CommonServicesExtension
{
public static IServiceCollection AddCommonServices(IServiceCollection services)
{
services.AddHttpClient();
services.AddNodaDateTime();
services.AddMemoryCache();
services.AddCurrencyExchange();
// Add and configure many things
return services;
}
}
现在你可以这样使用了:
CommonServicesExtension.AddCommonServices(serviceColletion);
但这有点丑陋且难以阅读,因此,只需将 this
添加到您的扩展方法中即可:
public static IServiceCollection AddCommonServices(this IServiceCollection services)
通过此更改,您可以像 net core 一样调用您的配置!
services.AddCommonServices();
在你的配置服务中,这样,你的配置方法从
public IServiceCollection ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddTransient<IHttpContextAccessor, HttpContextAccessor>();
services.AddDbContext<CoreContext>(options => options.UseMySql(Configuration.GetConnectionString("Core")));
services.AddDbContext<CoreReadOnlyContext>(options => options.UseMySql(Configuration.GetConnectionString("CORE_READONLY")));
services.AddDbContext<StatsContext>(options =>
options.UseMySql(Configuration.GetConnectionString("Stats")));
services.AddScoped<ProfileTokenGenerator>();
services.AddTransient<MailNotificationService>();
services.AddTransient<RegisterControllerService>();
services.AddScoped<OtherClass>();
services.AddTransient<MoreTransient>();
services.AddTransient<ThingsService>();
return services;
}
到
public IServiceCollection ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddContexts();
services.AddCommonServices();
services.AddOtherServices();
return services;
}
如您所见,更加简洁易读!
创建一个静态文件,例如;
public static class StartupConfiguration
{
public static void AddMyLogging(
this IServiceCollection services)
{
services.AddSingleton<ILoggerFactory, LoggerFactory>();
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>));
services.AddLogging(builder => builder.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace));
}
}
然后在你的 Startup class:
public void ConfigureServices(
IServiceCollection services)
{
services.AddMyLogging();
}
只调用 AddLogging
扩展方法就足够了。
services.AddLogging(builder => builder.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace));
因为,如果您查看此扩展方法的实现,您会发现 ILoggerFactory
和 ILogger<>
已经应该添加到服务中。
services.TryAdd(ServiceDescriptor.Singleton<ILoggerFactory, LoggerFactory>());
services.TryAdd(ServiceDescriptor.Singleton(typeof (ILogger<>), typeof (Logger<>)));