Net Core: ILogger в классе запуска: инкапсуляция в методе расширения

Я написал этот код регистрации в 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));

4 ответа

Решение

Хотя этот вопрос не может быть чисто стековым потоком, я думаю, что могу высказать свое мнение:

Проблема с методом ConfigureServices в том, что вам нужно определить все ваши зависимости, для более крупных систем это может означать болезненный метод длительной настройки, который может быть очень сложным и скучным в обслуживании.

Чтобы это исправить, вы можете упростить свой запуск, разделив все свои конфигурации, для этого вы можете использовать методы расширения C#, которые позволяют "расширять" класс (добавлять больше методов) без изменения исходного кода класс.

Методы расширения просты, просто возьмите статический класс со статическим методом:

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));
    }
}

А затем в вашем классе запуска:

    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<>)));

Ну, это может быть сделано так же, как написан метод расширения 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)); 
}
Другие вопросы по тегам