Search code examples
c#autofacioc-containerserilog

.NET Core 5 console app with IOC and Serilogging without microservice?


I need to create a simple .NET Core 5 Console App that uses IOC(Autofac), ILogging(Serilog) and a Message Queue(MQRabbit). I have done this before(exception Microsoft IOC instead of Autofac) in Console Apps that run microservices, this time I however need just a basic console app without hosting a service. How is this done?

I have this code from my microservice :

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

But 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.

Edit :

This is as far as I manage to get :

    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()
    {
        
    }
}

I get the exception when running it :

Cannot resolve parameter 'Microsoft.Extensions.Logging.ILogger1[ConnectorMockTest.BusinessLogicLayer.TestController] logger' of constructor 'Void .ctor(Microsoft.Extensions.Logging.ILogger1[ConnectorMockTest.BusinessLogicLayer.TestController])'.


Solution

  • I was under the impression that a Service host was mainly used when hosting webservice/webpage or likewise. There is however really nothing wrong to create a service in a "closed" console application that serves the application with Dependency Injection, Configuration and startup routines. Even if the application is just a fire and forget app.