Home > database >  How can I activate a service in the Program.cs in a .Net6 Console Application?
How can I activate a service in the Program.cs in a .Net6 Console Application?

Time:09-22

I have a .Net6 Console application.

I have a Startup.cs

public class Startup
    {
        public IConfiguration Configuration { get; private set; }

        public Startup(IConfiguration configuration)
        {
            this.Configuration = configuration;
        }

        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<Files>(Configuration.GetSection("Files"));
            services.AddLogging(configure => configure.AddSerilog());
            services.AddScoped<IHttpService, HttpService>();
        }
    }

then I have a Program.cs

class Program{
        static void Main(string[] args)
        {
            ...
            var builder = new ConfigurationBuilder().AddJsonFile($"appsettings.json", true, true);
            var config = builder.Build();
            ...
            // Here is what I'm trying to do...
            var svc = ActivatorUtilities.CreateInstance<IHttpService>();
        }
}

but I'm not sure how to solve for ServiceProvider enter image description here

then I see this guy who wired up his Program.cs file w/o a Startup.cs and he was able to get his service from the ActivatorUtilities.CreateInstance<T>(...) so I'm wondering if I should too throw away the Startup.cs or is there a better way (I hope there is)

enter image description here

CodePudding user response:

Personally, I would dump the Startup.cs and put everything in Program.cs.

Based on the method signature of the ActivatorUtilities.CreateInstance<T> method you need to pass in the ServiceProvider. How do you get the ServiceProvider?

Options:

  1. Create/build a Host and use Host.Services. This method works best in my opinion because in the context of a Host you can use DI easily in other places.
  2. If you don't want a Host you can do something similar to this and generate the ServiceProvider from services.BuildServiceProvider();.

CodePudding user response:

Ended up with this:

internal class Program
    {
        static void Main(string[] args)
        {
            var builder = new ConfigurationBuilder();
            BuildConfig(builder);

            Log.Logger = new LoggerConfiguration()
                .ReadFrom.Configuration(builder.Build())
                .Enrich.FromLogContext()
                .WriteTo.Console()
                //.WriteTo.File()
                .CreateLogger();

            Log.Logger.Information("Application Starting");

            var host = Host.CreateDefaultBuilder()
                .ConfigureServices((context, services) => { 
                    services.AddTransient<IGreetingsService, GreetingsService>();
                })
                .UseSerilog()
                .Build();

            var svc = ActivatorUtilities.CreateInstance<GreetingsService>(host.Services);
            svc.Run();
        }

        static void BuildConfig(IConfigurationBuilder builder)
        {
            builder.SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}", optional:true)
                .AddEnvironmentVariables();
        }
    }
  • Related