Как правильно внедрить Serilog Contextual logger инъекцию для Autofa c в чистой архитектуре? - PullRequest
4 голосов
/ 25 марта 2020

Кстати, я пытаюсь внедрить Serilog Contextual logger инъекцию для Autofa c в моем базовом приложении Clean Architecture SPA.

Структура проекта:

enter image description here

enter image description here

В моем проекте Autofa c находится в проекте инфраструктуры CL, как показано ниже:

Ссылочный код:

public static class ContainerSetup
{
    public static IServiceProvider InitializeWeb(Assembly webAssembly, IServiceCollection services) =>
        new AutofacServiceProvider(BaseAutofacInitialization(setupAction =>
        {
            setupAction.Populate(services);
            setupAction.RegisterAssemblyTypes(webAssembly).AsImplementedInterfaces();
        }));

    public static Autofac.IContainer BaseAutofacInitialization(Action<ContainerBuilder> setupAction = null)
    {
        var builder = new ContainerBuilder();

        var coreAssembly = Assembly.GetAssembly(typeof(BaseEntity));
        var infrastructureAssembly = Assembly.GetAssembly(typeof(P2PRepository));
        builder.RegisterAssemblyTypes(coreAssembly, infrastructureAssembly).AsImplementedInterfaces();

        setupAction?.Invoke(builder);
        return builder.Build();
    }
}

и зарегистрируйте контейнер Autofa c в классе запуска, как показано ниже:

public IServiceProvider ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));

    services.AddDefaultIdentity<ApplicationUser>()
        .AddEntityFrameworkStores<ApplicationDbContext>();

    services.AddIdentityServer()
        .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();

    return ContainerSetup.InitializeWeb(Assembly.GetExecutingAssembly(), services);
}

Что я имею пробовал еще?

Я успешно внедрил Serilog в свой веб-проект

public static int Main(string[] args)
    {
        Log.Logger = new LoggerConfiguration()
        .MinimumLevel.Debug()
        .MinimumLevel.Override("Microsoft", LogEventLevel.Information)
        .Enrich.FromLogContext()
        .WriteTo.Console()
        .WriteTo.File(
            @"D:\home\LogFiles\Application\myapp.txt",
            rollingInterval: RollingInterval.Day,
            outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}"
            )
        .CreateLogger();

        try
        {
            Log.Information("Starting web host");
            CreateWebHostBuilder(args).Build().Run();
            return 0;
        }
        catch (Exception ex)
        {
            Log.Fatal(ex, "Host terminated unexpectedly");
            return 1;
        }
        finally
        {
            Log.CloseAndFlush();
        }
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .UseSerilog();
}

после реализации выше serilog и его зависимостей, я обнаружил, что Serilog предоставляет реализацию для Autofa c также. Итак, я запутался, где я должен использовать фактическую реализацию Serilog в веб-проекте или инфраструктурном проекте? Должен ли я вернуть обратно весь код из моего program.cs файла и внедрить Serilog и установить его зависимости в проекте Infrastructure, используя следующий код?

Первая установка Serilog Dependency:

Install-Package AutofacSerilogIntegration

Then when configuring the Autofac container, call RegisterLogger():

Log.Logger = new LoggerConfiguration()
.WriteTo.Console()
.CreateLogger();

var builder = new ContainerBuilder();

var coreAssembly = Assembly.GetAssembly(typeof(BaseEntity));
var infrastructureAssembly = Assembly.GetAssembly(typeof(P2PRepository));
builder.RegisterAssemblyTypes(coreAssembly, infrastructureAssembly).AsImplementedInterfaces();

setupAction?.Invoke(builder);
builder.RegisterLogger(); // Here register serilog
return builder.Build();

Простой вопрос:

Как правильно реализовать интеграцию SerilogAutofa c в моем Чистом проекте?

Ответы [ 2 ]

3 голосов
/ 17 апреля 2020

Как правильно реализовать интеграцию SerilogAutofa c в моем проекте Clean?

Это вопрос, основанный на мнении, означающий, что на этот вопрос нет однозначного ответа.

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *1003* 1007 * * * * * * * * * * * * * * * * * * * * * * * * * * * *1003* 1007 * Мое мнение, имейте в виду, что для внедрения Serilog внедрения контекстного логгера для Autofa c, вы делаете две вещи:

  1. Добавление Serilog
  2. Добавление контекстных регистраторов с использованием Autofa c

Код в Main - для первой цели согласно инструкции . И помните, это чисто Serilog для интеграции с ASP. Net Core. Так что, на сегодняшний день, Autofa c не задействован. То есть, если вы удалите зависимость Autofa c из ваших проектов, ваше приложение все равно должно использовать Serilog.

Код в ContainerSetup - это то место, где вы ввели Autofa c в ASP. NET Ядро, и с этого момента ASP. NET Ядро знает, как использовать Autofa c в качестве контейнера DI. Если вы хотите специально настроить контекстные регистраторы, используя Autofa c, тогда ContainerSetup - правильное место для этого.

С учетом вышесказанного, чтобы решить, где настроить регистраторы Задайте себе простой вопрос:

Хотите ли вы Serilog независимо от Autofa c?

Если да, то не инициализируйте регистраторы Serilog в вашем Autofa c Speci c типов.

1 голос
/ 16 апреля 2020

Рекомендуемый способ соединения Autofac с ASP. NET Core 2.1 и 2.2 :

services.AddAutofac();

Код примеры в официальной документации утверждают, что метод возврата IServiceProvider:

является старым, не рекомендуемым способом и НЕ ПОДДЕРЖИВАЕТСЯ в ASP. NET Core 3.0 +.

После регистрации Autofac в службах вам просто нужно использовать метод в своем классе Startup для регистрации зависимостей:

public void ConfigureContainer(ContainerBuilder builder)
{
    // Register your own things directly with Autofac, like:
    builder.RegisterModule(new MyApplicationModule());
}

Ссылка на документацию здесь .

Как только Autofac подключен правильно, вопрос о том, как вы зарегистрируете Serilog, зависит от вкуса / мнения, поскольку средство разрешения зависимостей будет корректно разрешать все регистрации (Autofac и IServiceCollection). Я предпочитаю вести регистрацию через встроенный IServiceCollection, где это возможно, потому что это стандартный и более привычный подход. Так что я бы сохранил UseSerilog() версию.

Обновление: на втором этапе, вам нужно go для UseSerilog(), потому что именно это регистрирует Serilog реализацию ASP. NET ILoggerFactory, который следует использовать для регистрации. С другой стороны, builder.RegisterLogger(); регистрирует только Serilog ILogger с Autofa c. Он ничего не подключает к MVC.

Что касается вашего метода InitializeWeb в CL проекте, я бы помнил при смешивании ASP. NET Ядро и зависимости уровня данных в одной DLL. Если CL проект потенциально может развиваться в многократно используемом пакете Nuget для нескольких проектов, наличие жестко запрограммированной версии ASP. NET Ядро в dll может стать проблемой.

...