【问题标题】:.NET Core 5 console app with IOC and Serilogging without microservice?.NET Core 5 控制台应用程序与 IOC 和 Serilogging 没有微服务?
【发布时间】:2022-01-18 13:59:11
【问题描述】:

我需要创建一个简单的 .NET Core 5 控制台应用程序,它使用 IOC(Autofac)、ILogging(Serilog) 和消息队列(MQRabbit)。我以前在运行微服务的控制台应用程序中做过这个(Microsoft IOC 而不是 Autofac),但是这次我只需要一个基本的控制台应用程序而不托管服务。这是怎么做到的?

我的微服务中有这段代码:

public static void Main(string[] args) {
    Log.Logger = new LoggerConfiguration().DefaultLoggerSetup<Program>();
    var serviceName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;

    var configurationBuilder = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();
    var appSettings = configurationBuilder.Get<AppSettings>();

    Log.Information("{@serviceName} microservice starting up.", serviceName);
    Host.CreateDefaultBuilder(args)
        .UseMQ(context => context.UseSettings(appSettings.MQSettings))
        .UseSerilog((hostingContext, loggerConfiguration) => loggerConfiguration.ReadFrom.Configuration(hostingContext.Configuration))
        .ConfigureServices((hostContext, services) =>
        {
            services
                .AddHostedService<MyService>()
                .Configure<MQSettings>(configurationBuilder.GetSection("MQSettings"))
                .AddTransient<IController, Controller>()
                ...
        })
        .Build().Run();
    Log.Information("{@serviceName} microservice closing down.", serviceName);
}

但是在这种情况下我不需要托管任何东西,它应该是一个简单的基本控制台应用程序,在 MQ 上具有日志记录、注入和一些 I/O。

编辑:

这是我设法得到的:

    public class Program
    {
        static void Main(string[] args)
        {
            var serviceName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
    
            var configurationBuilder = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();
            var appSettings = configurationBuilder.Get<AppSettings>();
            CompositionRoot(configurationBuilder).Resolve<ITestController>().PlaceTrestment1OnMQTest();
        }
        private static IContainer CompositionRoot(IConfigurationRoot configurationRoot)
        {
            var serilog = new LoggerConfiguration().ReadFrom.Configuration(configurationRoot).CreateLogger();
            var loggerFactory = new LoggerFactory().AddSerilog(serilog);
            Microsoft.Extensions.Logging.ILogger logger = loggerFactory.CreateLogger("Logger");
    
            var builder = new ContainerBuilder();
            builder.Register<Microsoft.Extensions.Logging.ILogger>((c, p) =>
            { return logger; });
            //builder.Register<Microsoft.Extensions.Logging.ILogger>((c, p) =>
            //{ return new LoggerConfiguration().ReadFrom.Configuration(configurationRoot).CreateLogger(); });
            builder.RegisterType<TestController>().As<ITestController>();
            return builder.Build();
        }
    }
}
public class TestController : ITestController
{
    private ILogger<TestController> _logger;

    public TestController(ILogger<TestController> logger)
    {
        _logger = logger;
    }
    public void PlaceTrestment1OnMQTest()
    {
        
    }
}

运行时出现异常:

无法解析参数“Microsoft.Extensions.Logging.ILogger1[ConnectorMockTest.BusinessLogicLayer.TestController] logger' of constructor 'Void .ctor(Microsoft.Extensions.Logging.ILogger1[ConnectorMockTest.BusinessLogicLayer.TestController])”。

【问题讨论】:

  • 你昨天不是问过同样的问题吗?没有“微服务”。这只是一个营销术语。如果你使用dotnet new worker,你会得到你想要的开箱即用的东西。此外,.NET 5 不是长期版本,goes out of support in May 2022。 LTS 版本是 .NET 6。您应该寻找 .NET 6 的答案,除非您想在完成项目后立即迁移。
  • I dont need to host anything in this case, it should be a just basic console app with logging, injection and some I/O on a MQ. 这就是主机所做的。它创建配置、日志记录、DI 中间件并将所有这些组合在一起。完成后,您可以使用var myClass=app.Services.GetRequiredService&lt;TheClassThatDoesTheWork&gt;() 并开始使用该对象,例如myClass.DoWhatever();
  • 您可能应该解释您想要做什么,而不是您认为代码的样子。你想创建一个名为Controller 的类并使用它还是只是演示代码?您将在 .NET 6 中使用的代码也将比您发布的代码简单得多。
  • 我确实发布了关于如何将注入添加到控制台应用程序的帖子。我的印象是最好只使用另一个注射包,这就是我的目标。当我只想快速启动并忘记操作时,似乎没有必要启动和托管服务。构建一个对象,将其放在 MQ 上,然后关闭。您所说的新工作人员似乎仍然是您托管的服务。
  • 好的,所以要使用日志记录和注入,我需要将应用程序视为一组以某种方式托管的服务,即使是快速启动并忘记主应用程序操作类\方法?

标签: c# autofac ioc-container serilog


【解决方案1】:

注册非泛型ILogger 不会自动注册泛型ILogger&lt;T&gt;,而这正是您想要做的。

ILogger 注入TestController 构造函数而不是ILogger,假设其余代码有效,它应该可以正常工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-29
    相关资源
    最近更新 更多