I want to read my custom environment variables in .NET 5 or .NET 6. I have some problems. I can only read environment variables with the DOTNET_ and ASPNETCORE_ prefixes:
For example, I can't read that MyKey=MyValue:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostContext,configuration) =>
{
string myKey = hostContext.Configuration["MyKey"];
configuration.AddJsonFile($"Airlines/{myKey}.json");
})
.ConfigureServices((hostContext, services) =>
{
services.AddRabbitMQ();
services.AddSingleton<NiraAvailableFlightsConsumer>();
services.AddOptions<AirlineOptions>()
.Bind(hostContext.Configuration);
});
The documentation for the default builder says:
Loads host configuration from:
Environment variables prefixed with DOTNET_.
So your variable is not read as part of the host context configuration. You can tell the builder to load all environment variables by adding the ConfigureHostConfiguration call to your startup:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureHostConfiguration(config =>
{
config.AddEnvironmentVariables();
})
.ConfigureAppConfiguration((hostContext, configuration) =>
{
string myKey = hostContext.Configuration["MyKey"];
configuration.AddJsonFile($"Airlines/{myKey}.json");
})
.ConfigureServices((hostContext, services) =>
{
....
});
Related
My current code is like this:
public static IWebHostBuilder CreateWebHostBuilder(string[] args) {
return WebHost.CreateDefaultBuilder(args)
.ConfigureLogging((hostingContext, logging) => {
logging.AddFilter("Microsoft.AspNetCore.SignalR", LogLevel.Debug);
logging.AddFilter("Microsoft.AspNetCore.Http.Connections", LogLevel.Debug);
})
.UseSerilog(Log.Logger)
I now get deprication error:
warning CS0618: 'SerilogWebHostBuilderExtensions.UseSerilog(IWebHostBuilder, ILogger, bool, LoggerProviderCollection)' is obsolete: 'Prefer UseSerilog() on IHostBuilder'
My understanding is I need to now create the logger like this:
public static void Main(string[] args) {
Log.Logger = new LoggerConfiguration()
// set filters ???
.CreateLogger();
and then just have UseSerilog() in CreateWebHostBuilder
But how do I set equivalent filters in LoggerConfiguration ? I can't seem to find relevant examples.
That error is telling you to move away from Microsoft.AspNetCore.Hosting.IWebHostBuilder to Microsoft.Extensions.Hosting.IHostBuilder.
IWebHostBuilder is for .NET Core 2, see the documentation.
Your code would look like below.
(Also renamed that method.)
public static IHostBuilder CreateHostBuilder(string[] args)
{
return Host.CreateDefaultBuilder(args)
.ConfigureLogging((hostingContext, logging) => {
logging.AddFilter("Microsoft.AspNetCore.SignalR", LogLevel.Debug);
logging.AddFilter("Microsoft.AspNetCore.Http.Connections", LogLevel.Debug);
})
.UseSerilog(Log.Logger);
}
If you can't migrate, you'll have to pick an older version of Serilog.
I want to use NopCommerce libraries for a console project (for migrate data transfer).
I create a console project and add the base libraries (Nop.Core, Nop.Data, Nop.Service, Nop.Web.Freamework) to it, I also copy the App_Data folder.
I also use Class Startup.cs to run the project
namespace Nop.Console
{
class Program
{
static void Main(string[] args)
{
using var host = Host.CreateDefaultBuilder(args)
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureWebHostDefaults(webBuilder => webBuilder
.ConfigureAppConfiguration(config =>
{
config
.AddJsonFile(NopConfigurationDefaults.AppSettingsFilePath, true, true)
.AddEnvironmentVariables();
})
.UseStartup<Startup>())
.Build();
var engine = EngineContext.Create();
var cs = engine.Resolve<ICategoryService>();
System.Console.WriteLine("Hello World!");
}
}
}
But engine.Resolve(); return null;
Any idea?
I'm not 100% sure if this is the best solution, but at least works for me for NopCommerce 4.40.4. The code in my Console application is following:
/// <summary>
/// EngineContextInitializer
/// </summary>
public static class EngineContextInitializer
{
/// <summary>
/// Runs this instance.
/// </summary>
public static async Task<IHost> RunAsync()
{
string[] args = Array.Empty<string>();
var host = Host.CreateDefaultBuilder(args)
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureWebHostDefaults(webBuilder => webBuilder
.ConfigureAppConfiguration(config =>
{
config
.AddJsonFile(NopConfigurationDefaults.AppSettingsFilePath, true, true)
.AddEnvironmentVariables();
})
.UseStartup<Startup>())
.Build();
//start the program, a task will be completed when the host starts
await host.StartAsync();
return host;
}
}
The usage of EngineContextInitializer is following:
private async Task GetProductById(int id)
{
using var host = await EngineContextInitializer.RunAsync();
IEngine engine = EngineContext.Current;
var productService = engine.Resolve<IProductService>();
var product = await productService.GetProductByIdAsync(id);
await host.StopAsync();
}
So what does make the difference between your and mine code?
I'm running the code:
await host.StartAsync();
Most importantly I'm disposing IHost after I got the product from IProductService.
On the line is the difference:
var host = Host.CreateDefaultBuilder(args)
And 1 more thing, you don't need to call EngineContext.Create(), because if you check the class and Current getter you will see the following code:
/// <summary>
/// Gets the singleton Nop engine used to access Nop services.
/// </summary>
public static IEngine Current
{
get
{
if (Singleton<IEngine>.Instance == null)
{
Create();
}
return Singleton<IEngine>.Instance;
}
}
Please don't forget to dispose IHost as it implements IDisposable to avoid memory leaks.
Disclaimer: I'm not part of NopCommerce dev team, usage is at your own risk. Please follow official NopCommerce documentation or response on the topic on their website (documentation, forum or GitHub).
I'm developing a .NET core 3.1 Console application (web-api).
I use a Serilog service (it is basically using the Microsoft.Extensions.Logging).
The Serilog is injected and can be used in the FW Controllers methods.
Now - I need something a little bit different - Whenever the system is starting up (after being down) I need to make an http post request - you can see it when executing the ConnectionInitiator.Initiate(), in the startup method. In that same scope (method\class) - I need to use the logger, in order to log some data. Now - If the request would be through the controller - the logger, would be available (by the DI).
To make a long story short - I need somehow to inject the Ilogger to the class or to make it available in some other way. I've tried use the logger in the startUp, but this seems to be impossible (since .net core 3.0 - if I understand correctly)
See my code:
Program.cs:
public class Program
{
public static void Main(string[] args)
{
var loggerConfig = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
//Reading the appconfig.json
Log.Logger = new LoggerConfiguration().ReadFrom.Configuration(loggerConfig).CreateLogger();
try
{
Log.Information("System Started up");
CreateWebHostBuilder(args).Build().Run();
}
catch (Exception ex)
{
Log.Fatal(ex, "THE APPLICATION FAILED TO START UP");
}
finally
{
Log.CloseAndFlush();
}
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args)
{
return WebHost.CreateDefaultBuilder(args).ConfigureLogging((context, logging) =>
{
logging.ClearProviders();
}).UseSerilog().UseStartup<Startup>();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
StartUp.cs
public class Startup
{
public Startup(IConfiguration configuration/*, Microsoft.Extensions.Logging.ILogger logger*/)
{
Configuration = configuration;
ConnectionInitiator.Initiate(configuration/*, logger*/);
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddCors();
services.AddControllers();
services.AddLogging(loggingBuilder => loggingBuilder.AddSerilog(dispose: true));
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseCors(builder => builder.AllowAnyHeader().AllowAnyMethod().SetIsOriginAllowed((host) => true).AllowCredentials());
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseAuthentication();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
ConnectionInitiator.cs:
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;
namespace AAA.BL
{
public static class ConnectionInitiator
{
private static readonly object threadlock = new object();
private static MyConfig myConfig;
private static ILogger ilogger;
/*
public ConnectionInitiator(ILogger _logger)
{
ilogger = _logger;
}
*/
public static void/*async Task*/ Initiate(IConfiguration configuration/*, ILogger ilogger*/)
{
HttpRequester httpRequester = new HttpRequester();
if (myConfig == null)
{
myConfig = new myConfig(configuration);
}
IssueOTPResponse response = /*await*/ httpRequester.PostSomething(myConfig, ilogger).Result; //Double check thread safe singleton implementation
if (response.ststuacode != 200)
{
ilogger.logcritical($"critical error when initiate connection (connectioninitiator): {response.statusdescription}");
}
}
}
}
It seems like the answer is much simpler that I expected - By using the Serilog and was added as a service in the Configure method - It can be reached globally (in every place of the namepsace) by using the static class Log and its static method Logger, for example:
Log.Logger.Information("XXXXX");
i am using the following code in configureservices in startup.cs in netcore 3
Can someone show how i can do this a better way, how do i inject it into configure method? I need to access the database before dependency injection has resolved it but buildservices isnt recommended.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<bookingsstrathContext>(options => options.UseSqlServer(Configuration.GetConnectionString("MyEntities2")));
services.AddScoped<IMyAccountService, MyAccountService>();
var sp = services.BuildServiceProvider();
// Resolve the services from the service provider
var _myAccountService = sp.GetService<IMyAccountService>();
//get the local role from the local database
if (_myAccountService.IsUserInRole(context.Principal.GetUserGraphSamAccountName(), "Administrator"))
{
//myIdentity.AddClaim(new Claim(ClaimTypes.Role, "Administrator"));
context.Principal.AddUserSystemRole("Administrator");
}
}
You can add your account service in program.cs
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices(serviceCollection =>
serviceCollection.AddScoped<IMyAccountService, MyAccountService>())
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
and then you can use it in startup.cs
private readonly IMyAccountService _myAccountService;
public Startup(IConfiguration configuration, IMyAccountService AccountService)
{
Configuration = configuration;
_myAccountService = AccountService
}
I'm having trouble figuring out how to configure my application to use Key Vault in my Program.cs file with .NET Core 3.0 Preview. All examples I've found are with Web Host Builder, but that has been replaced with a Generic Host Builder in 3.0.
Here is the example code I've found using Web Host Builder:
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((ctx, builder) =>
{
var azureServiceTokenProvider = new AzureServiceTokenProvider();
var keyVaultClient = new KeyVaultClient(
new KeyVaultClient.AuthenticationCallback(
azureServiceTokenProvider.KeyVaultTokenCallback));
builder.AddAzureKeyVault(
"myendpoint", keyVaultClient, new DefaultKeyVaultSecretManager());
}
).UseStartup<Startup>()
.Build();
And here is what I have so far:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
var azureServiceTokenProvider = new AzureServiceTokenProvider();
var keyVaultClient = new KeyVaultClient(
new KeyVaultClient.AuthenticationCallback(
azureServiceTokenProvider.KeyVaultTokenCallback));
});
It's this line that I cannot figure out how to implement correctly:
builder.AddAzureKeyVault("myendpoint", keyVaultClient, new DefaultKeyVaultSecretManager());
Any helps/tips/advice/anything at all would be greatly appreciated!!
Got it working with the following code!!
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
}).ConfigureAppConfiguration((ctx, builder) =>
{
var azureServiceTokenProvider = new AzureServiceTokenProvider();
var keyVaultClient = new KeyVaultClient(
new KeyVaultClient.AuthenticationCallback(
azureServiceTokenProvider.KeyVaultTokenCallback));
builder.AddAzureKeyVault("myendpoint", keyVaultClient, new DefaultKeyVaultSecretManager());
});
}
The .net core 3.0 is in preview which is not stable and Perfect function.
.NET Core 3 was announced on May 7, 2019, at Microsoft Build. Currently preview builds are available. An official release is planned for September 2019. You could wait for Release version or give your feedback.