Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better Integration to Generic Host #391

Closed
hikalkan opened this issue Jul 25, 2018 · 9 comments
Closed

Better Integration to Generic Host #391

hikalkan opened this issue Jul 25, 2018 · 9 comments

Comments

@hikalkan
Copy link
Member

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/generic-host?view=aspnetcore-2.1

@hikalkan hikalkan added this to the Backlog milestone Oct 2, 2018
@hikalkan hikalkan modified the milestones: backlog, 0.21 Aug 14, 2019
@hikalkan hikalkan modified the milestones: 0.21, 0.20 Sep 10, 2019
@hikalkan hikalkan modified the milestones: 0.20, 0.21 Sep 20, 2019
@hikalkan hikalkan self-assigned this Oct 6, 2019
@hikalkan hikalkan mentioned this issue Oct 10, 2019
3 tasks
@hikalkan
Copy link
Member Author

Done for the Web project of the application startup template: 026cdc9
I will implement it in all startup template projects in v0.22. We will apply this for all projects in v1.0 (see #1094).

@hikalkan
Copy link
Member Author

hikalkan commented Oct 10, 2019

For existing applications.

1. Replace Serilog in the .csproj file

Old code:

<PackageReference Include="Serilog.AspNetCore" Version="2.1.1" />

New code:

<PackageReference Include="Serilog.Extensions.Hosting" Version="3.0.0" />

2. Update Program.cs

Old code:

public static IWebHost BuildWebHostInternal(string[] args) =>
    new WebHostBuilder()
        .UseKestrel()
        .UseContentRoot(Directory.GetCurrentDirectory())
        .UseIIS()
        .UseIISIntegration()
        .UseStartup<Startup>()
        .UseSerilog()
        .Build();

New code:

internal static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        })
        .UseAutofac()
        .UseSerilog();

Also change BuildWebHostInternal(args).Run(); to CreateHostBuilder(args).Build().Run();.

3. Update Startup.cs

Old code:

public class Startup
{
    public IServiceProvider ConfigureServices(IServiceCollection services)
    {
        services.AddApplication<MyProjectNameHttpApiHostModule>(options =>
        {
            options.UseAutofac();
        });

        return services.BuildServiceProviderFromFactory();
    }

    public void Configure(IApplicationBuilder app)
    {
        app.InitializeApplication();
    }
}

New code:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddApplication<MyProjectNameHttpApiHostModule>();
    }

    public void Configure(IApplicationBuilder app)
    {
        app.InitializeApplication();
    }
}

@lommez
Copy link

lommez commented Oct 22, 2019

Halil,
Just one note, If you remove the UseAutoFac() from here:

public class Startup
{
    public IServiceProvider ConfigureServices(IServiceCollection services)
    {
        services.AddApplication<MyProjectNameHttpApiHostModule>(options =>
        {
            options.UseAutofac();
        });

        return services.BuildServiceProviderFromFactory();
    }

    public void Configure(IApplicationBuilder app)
    {
        app.InitializeApplication();
    }
}

Is not possible to call context.Services.GetContainerBuilder() from AbpModule.ConfigureServices()

@maliming
Copy link
Member

@lommez

Try calling UseAutofac before the ConfigureWebHostDefaults method

internal static IHostBuilder CreateHostBuilder(string[] args) =>
	Host.CreateDefaultBuilder(args)
		.UseAutofac()
		.ConfigureWebHostDefaults(webBuilder =>
		{
			webBuilder.UseStartup<Startup>();
		})
		.UseSerilog();

@lommez
Copy link

lommez commented Oct 23, 2019

@maliming, in that way gives me another exception.
the container cannot resolve the dependencies.

here is the stacktrace:

   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.Populate()
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory..ctor(IEnumerable`1 descriptors)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine..ctor(IEnumerable`1 serviceDescriptors, IServiceProviderEngineCallback callback)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CompiledServiceProviderEngine..ctor(IEnumerable`1 serviceDescriptors, IServiceProviderEngineCallback callback)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor(IEnumerable`1 serviceDescriptors, ServiceProviderOptions options)
   at Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(IServiceCollection services, ServiceProviderOptions options)
   at Microsoft.Extensions.DependencyInjection.ServiceCollectionCommonExtensions.BuildServiceProviderFromFactory(IServiceCollection services)
   at MyModule.Worker.Startup.ConfigureServices(IServiceCollection services) in C:\xxxx\MyModule.Worker\Startup.cs:line 20
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Microsoft.AspNetCore.Hosting.ConfigureServicesBuilder.InvokeCore(Object instance, IServiceCollection services)
   at Microsoft.AspNetCore.Hosting.ConfigureServicesBuilder.<>c__DisplayClass9_0.<Invoke>g__Startup|0(IServiceCollection serviceCollection)
   at Microsoft.AspNetCore.Hosting.ConfigureServicesBuilder.Invoke(Object instance, IServiceCollection services)
   at Microsoft.AspNetCore.Hosting.ConfigureServicesBuilder.<>c__DisplayClass8_0.<Build>b__0(IServiceCollection services)
   at Microsoft.AspNetCore.Hosting.GenericWebHostBuilder.UseStartup(Type startupType, HostBuilderContext context, IServiceCollection services)
   at Microsoft.AspNetCore.Hosting.GenericWebHostBuilder.<>c__DisplayClass12_0.<UseStartup>b__0(HostBuilderContext context, IServiceCollection services)
   at Microsoft.Extensions.Hosting.HostBuilder.CreateServiceProvider()
   at Microsoft.Extensions.Hosting.HostBuilder.Build()
   at MyModule.Worker.Program.Main(String[] args) in C:\xxx\MyModule.Worker\Program.cs:line 34

@maliming
Copy link
Member

hi @lommez
Please share your Program.cs and Startup.cs code.

@lommez
Copy link

lommez commented Oct 23, 2019

here is the program.cs

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Serilog;
using Serilog.Events;
using System;
using System.IO;

namespace MyApp.Worker
{
    public class Program
    {
        public static int Main(string[] args)
        {
            var configuration = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                .AddEnvironmentVariables()
                .Build();

            Log.Logger = new LoggerConfiguration()
                .MinimumLevel.Debug()
                .MinimumLevel.Override("Microsoft", LogEventLevel.Information)
                .Enrich.WithProperty("Application", "MyAppWorker")
                .Enrich.FromLogContext()
                .WriteTo.File("Logs/logs.txt")
                .CreateLogger();

            try
            {
                Log.Information("Starting MyApp.Worker.");
                CreateHostBuilder(args).Build().Run();
                return 0;
            }
            catch (Exception ex)
            {
                Log.Fatal(ex, "MyApp.Worker terminated unexpectedly!");
                return 1;
            }
            finally
            {
                Log.CloseAndFlush();
            }
        }

        internal static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .UseAutofac()
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                })
                .UseSerilog();
    }
}

here is the startup.cs

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Serilog;
using System;
using Volo.Abp;

namespace MyApp.Worker
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddApplication<MyAppWorkerModule>(options =>
            {
                //options.UseAutofac();
                options.Services.AddLogging(c => c.AddSerilog());
                options.Configuration.UserSecretsAssembly = typeof(Startup).Assembly;
            });

            services.BuildServiceProviderFromFactory();
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
        {
            app.InitializeApplication();
        }
    }
}

@maliming
Copy link
Member

The code you should update your Startup class looks like this:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddApplication<MyAppWorkerModule>();
    }

    public void Configure(IApplicationBuilder app)
    {
        app.InitializeApplication();
    }
}
internal static IHostBuilder CreateHostBuilder(string[] args) =>
	Host.CreateDefaultBuilder(args)
		.UseAutofac()
		.ConfigureWebHostDefaults(webBuilder =>
		{
			webBuilder.UseStartup<Startup>()
                        .ConfigureAppConfiguration((context, config) =>
                        {
                            config.AddUserSecrets(typeof(MyAppWorkerModule).Assembly);
                        });
		})
		.UseSerilog();

see #391 (comment)

@lommez
Copy link

lommez commented Oct 23, 2019

Thanks @maliming

The problem was calling services.BuildServiceProviderFromFactory() within Startup.ConfigureServices()

When removed that method everything works fine

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants