Inject configuration in Startup.cs

I try to get my .NETCore console application running but currently with no luck at all. It crashes with some strange errors.

First how can I inject configuration values? In my main (Programm.cs) I have

var host = new WebHostBuilder()
             .UseKestrel()
             .UseContentRoot(Directory.GetCurrentDirectory())
             .UseStartup<Startup>()
             .UseUrls(Environment.GetEnvironmentVariable("ASPNETCORE_URLS") ?? ListeningOn)
             .Build();
host.Run();

My startup.cs looks similar to the one shown here:

public class Startup
{
    public IConfiguration Configuration { get; }
    public Startup(IConfiguration configuration) => Configuration = configuration;  // This method gets called by the runtime. Use this method to add services to the container.
    
    public void ConfigureServices(IServiceCollection services)
    {
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        
        app.UseServiceStack(new AppHost
        {
            AppSettings = new NetCoreAppSettings(Configuration)
            
        });

        app.Run(context =>
        {
            context.Response.Redirect("/metadata");
            return Task.FromResult(0);
        });
    }
}

Configuration contains one item of type MemoryConfigurationProvider with defaults that I have never set:


Instead I like to have a Configuration loaded from a JSON file like so:

        var builder = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json");

        var config = builder.Build();

How can I pass my config variable to the Startup.cs class?? I tried to use WebBuilder.AddConfiguration(config).... but no luck with that.

No matter what configuration I add, it crashes here:

app.UseServiceStack(new AppHost
{
      AppSettings = new NetCoreAppSettings(Configuration)
});

with

System.Exception: Failed loading types, last assembly ‘BizBusLicenseServer.ServiceInterface, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null’, type: ‘’ —> System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module)
at System.Reflection.RuntimeModule.GetTypes()
at System.Reflection.Assembly.GetTypes()
at ServiceStack.Host.ServiceController.GetAssemblyTypes(Assembly[] assembliesWithServices)
— End of inner exception stack trace —
at ServiceStack.Host.ServiceController.GetAssemblyTypes(Assembly[] assembliesWithServices)
at ServiceStack.Host.ServiceController.<>c__DisplayClass5_0.<.ctor>b__0()
at ServiceStack.Host.ServiceController.Register(ITypeFactory serviceFactoryFn)
at ServiceStack.Host.ServiceController.Init()
at ServiceStack.ServiceStackHost.Init()
at ServiceStack.NetCoreAppHostExtensions.UseServiceStack(IApplicationBuilder app, AppHostBase appHost)
at BizBusLicenseServer.Startup.Configure(IApplicationBuilder app, IHostingEnvironment env) in /home/tbednarz/Projects/BizBusLicenseServer/BizBusLicenseServer/Startup.cs:line 24

The LoaderException contains a list of assemblies I have added in my Dependencies:


Any idea what is missing here?

Do I need to set a Dependency path somewhere?
I run JetBrains Rider on CentOS 7.

You basically have a dependency loading issue. Where it couldn’t load one or more Types because one or more of the dependencies they reference couldn’t be loaded.

Don’t know of an easy solution to identify the problematic Types/.dll’s except to try loading them in the host project (i.e. before the AppHost is initialized), e.g:

var d1 = new BizBusLicenseServer.ServiceInterface.TypeInNamespace();
var d2 = new BedDtos.TypeInNamespace();

I just got one step further with the FileNotFound exception. Fact is, the assemblies in the LoaderException list where NOT in my Dependencies folder (Rider shows all different Dependencies in different folders). However I did NOT add them because the code compiled without error.

Now I just added all assemblies in the list, and I got a step further! Don’t know what is going on here, seems to be a lot different then with VisualStudion on Windows targeting 4.6.1.

But I now have another Issue when retrieving configuration values. Need to debug further and come back, if I cannot find it.

This is really strange! The next crash was in AppHost.Configure(), the file Microsoft.Extensions.Configuration.Binder was missing when I called

var redisServer = AppSettings.Get<string>("RedisServer");

Again no error from the compiler, but crash at runtime. Does anybody know if this is a .NET Core thing or a JetBrains Rider issue?? It is my first port from 4.6.1 to .NET Core 2, so I have absolutely no experience. Also I was developing on Windows for the 4.6.1 servers, now I am on CentOS 7.

Also I had to change the configuration loading to follow the .NET 2.0 “way” like so:

    static void Main(string[] args)
    {
        var licenseKeyText = ...;
        Licensing.RegisterLicense(licenseKeyText);

        var logDir = $@"/home/tbednarz/logs/{LsConstants.ProductName}";

        if (!Directory.Exists(logDir))
            Directory.CreateDirectory(logDir);
        
        Log.Information("Starting web host");           
        Log.Logger = new LoggerConfiguration()
            .MinimumLevel.Debug()
            .MinimumLevel.Override("Microsoft", LogEventLevel.Information)
            .Enrich.FromLogContext()
            .WriteTo.Console()
            .WriteTo.File(Path.Combine(logDir, "log-.log"), rollingInterval: RollingInterval.Day)
            .CreateLogger();
        
        BuildWebHost().Run();
        
        Console.Write($"\nHit any key to exit ...\n");
        Console.ReadKey(true);
    }

    private static IWebHost BuildWebHost()
    {
        return new WebHostBuilder()
            .UseKestrel()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseSerilog()
            .ConfigureAppConfiguration((builderContext, config) =>
            {
                config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
            })
            .UseDefaultServiceProvider((context, options) =>
            {
                options.ValidateScopes = context.HostingEnvironment.IsDevelopment();
            })
            .UseStartup<Startup>()
            .Build();
    }

My first solution was a copy of what the dotnet-new selfhost MyTestApplication generated. This seems to be the .NET Core 1.3 way.

Ok, continue my porting stuff, see what surprises follow next… :grin:

Rider doesn’t build or run .NET Core App’s itself, it uses the same dotnet tools that you would use to build and run your App on the command-line, e.g:

dotnet build
dotnet run

I’m not sure why you’re trying to build on CentOS if you’re not familiar with it, just build on windows and deploy to Linux.

You can publish your .NET Core App with:

$ dotnet publish -c Release

Then use rsync to copy the parts that have changed:

$ rsync -avz -e 'ssh' bin/Release/netcoreapp2.0/publish/ user@domain.org :/home/deploy/the-app

Which you can run by running the Host project .dll, e.g:

$ dotnet TheApp.dll

Hmm, and how can I debug a .NET Core server on Windows? E.g. paths for files are completely different, there is no C:\ etc on Linux.

If paths are really your issue, then sure debug locally when needed, but I don’t run into any path issues accessing files via the Virtual File System.

But Microsoft has published a few guides for remote debugging a .NET Core App on Linux even running inside Docker. I don’t know if that’s Rider supports remote debugging a .NET Core process on Linux.