In my API project, Startup.cs file I have the following:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
app.UseMvc();
loggerFactory.AddAWSProvider(Configuration.GetAWSLoggingConfigSection(),
(logLevel, message, exception) => $"[{DateTime.UtcNow}] {logLevel}: {message}");
This works fine for API project. How would I register this in Structuremap Container?
var container = new StructureMap.Container(
c =>
{
c.For(typeof(ILogger<>)).Use(typeof(Logger<>));
c.For<ILoggerFactory>..../// use what?
}
If I understood you correctly, you need to register existing instance of loggerFactory. There is an overload of Use method that takes existing instance:
var container = new StructureMap.Container(
c =>
{
c.For(typeof(ILogger<>)).Use(typeof(Logger<>));
c.For(typeof(ILoggerFactory)).Use(loggerFactory);
});
See Registering Existing Objects for some more details.
Related
From what I understand, when enabled CORS accordingly, the response model should include the following header information (provided that I want to allow everything):
Access-Control-Allow-Origin: *
Access-Control-Allow-Method: *
Access-Control-Allow-Header: *
Enabling it in Startup:
public void ConfigureServices(IServiceCollection services)
{
//...
services.AddCors();
services.ConfigureCors(options =>
{
options.AddPolicy("AllowAll", p => p.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader().AllowCredentials());
});
//...
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
//...
app.UseCors("AllowAll");
//...
}
The problem is that none of these headers are returned and I get the following error when trying to request from the API:
Response to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost' is therefore not allowed access.
Make sure you add app.UseCors before app.UseMvc in your Startup.Configure method, because you need the CORS middleware to be applied before the MVC middleware.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
...
//Add CORS middleware before MVC
app.UseCors("AllowAll");
app.UseMvc(...);
}
Otherwise the request will be finished before the CORS middleware is applied. This is because UseMvc calls UseRouter which ends up adding the RouterMiddleware, and this middleware only executes the next configured middleware when a route handler wasn't found for the request.
In .Net Core Web API 5.0 in Configure method you have to add app.UseCors before other methods, like that:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
...
}
//add CORS
app.UseCors();
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
I have WebApi project and this is my dependancy registration code:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<MyDatabaseContext>(opt=> opt.UseSqlServer(Configuration.GetConnectionString("conStr")));
services.RegisterEasyNetQ("host=localhost;username=admin;password=admin");
services.AddTransient(typeof(CreateOrderHandler));
services.AddTransient(typeof(OrderFinishedHandler));
services.AddTransient(typeof(OrderPaidHandler));
services.AddControllers();
}
and I resolve these services run immediately after the project started by this code:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
app.ApplicationServices.GetService(typeof(CreateOrderHandler));
app.ApplicationServices.GetService(typeof(OrderPaidHandler));
app.ApplicationServices.GetService(typeof(OrderFinishedHandler));
}
this code works properly when I run my project by dotnet command but when i am debugging my code in rider I am getting this Exception:
System.InvalidOperationException: Cannot resolve 'ApiProject.Order.CreateOrderHandler' from root provider because it requires scoped service 'ApiProject.Order.MyDatabaseContext'.
I'd like to send an email in my Configure method inside my Startup.cs file, when I receive exceptions.
I'm using IEmailSender and registering it in Startup.cs file like this for the rest of the application.
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IEmailSender, EmailSender>();
}
But now I want to use it below in the Configure method when I receive an exception, but I'm not sure how to instantiate it and/or use _emailSender, which is a IEmailSender that usually gets injected into the constructor of the class using it, but in this case (Startup.cs) I can't inject it because it hasn't been defined until the ConfigureServices method gets run and adds it as a service.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, Seed seeder)
{
app.UseExceptionHandler(builder => { builder.Run(async context => {
// where _emailSender is a IEmailSender emailSender
await _emailSender.SendEmailAsync("someone#gmail.com", "some subject", "hey an exception error!");
});
});
}
Extract the service provider from the context and use that to resolve the desired types
public void Configure(IApplicationBuilder app, IHostingEnvironment env, Seed seeder) {
//...
app.UseExceptionHandler(errorApp => {
errorApp.Run(async context => {
IServiceProvider services = context.RequestServices;
IEmailSender emailSender = services.GetRequiredService<IEmailSender>();
UserExceptionOptions options = services.GetRequiredService<IOptions<UserExceptionOptions>>().Value;
await emailSender.SendEmailAsync(options.ExceptionEmailAddress, "some subject", "hey an exception error!");
});
});
//...
}
The resolved services can then be used as needed
I am looking to inject a kafka producer as a singleton in my app. It currently has two steps required when disposing the instance. First, you must flush the buffer, second call dispose. To increase performance, this should only happen when messages are no longer being processed.
My solution for ASP.NET core, is to use the AddSingleton() method in DI and then use ApplicationLifetime.ApplicationStopping.Register to register a callback that will flush and dispose the producer. I followed the tutorial found here:https://andrewlock.net/four-ways-to-dispose-idisposables-in-asp-net-core/
putting together a quick test I did the following in my Startup class:
public void ConfigureServices(IServiceCollection services)
{
var producerConfig = new Dictionary<string, object>
{
{ "bootstrap.servers", "192.168.99.100:9092" },
{ "client.id", Dns.GetHostName() },
{ "api.version.request", true }
};
services.AddSingleton(new Producer<Null, string>(producerConfig, null, new StringSerializer(Encoding.UTF8)));
services.AddMvc();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IApplicationLifetime lifetime)
{
loggerFactory.AddConsole();
app.UseMvc();
app.UseWebSockets();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
lifetime.ApplicationStopping.Register(flushAndDispose, app.ApplicationServices.GetRequiredService<Producer>());
}
but when it runs I get the following error:
An exception of type 'System.InvalidOperationException' occurred in
Microsoft.Extensions.DependencyInjection.Abstractions.dll but was not
handled in user code: 'No service for type 'Confluent.Kafka.Producer'
has been registered.'
The assumption is also that Producer<T1,T2> is derived from Producer
you did not explicitly register a Producer with the service collection so the provider is unaware of how to resolve it.
services.AddSingleton<Producer>(
c => new Producer<Null, string>(producerConfig, null,
new StringSerializer(Encoding.UTF8)));
From what I understand, when enabled CORS accordingly, the response model should include the following header information (provided that I want to allow everything):
Access-Control-Allow-Origin: *
Access-Control-Allow-Method: *
Access-Control-Allow-Header: *
Enabling it in Startup:
public void ConfigureServices(IServiceCollection services)
{
//...
services.AddCors();
services.ConfigureCors(options =>
{
options.AddPolicy("AllowAll", p => p.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader().AllowCredentials());
});
//...
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
//...
app.UseCors("AllowAll");
//...
}
The problem is that none of these headers are returned and I get the following error when trying to request from the API:
Response to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost' is therefore not allowed access.
Make sure you add app.UseCors before app.UseMvc in your Startup.Configure method, because you need the CORS middleware to be applied before the MVC middleware.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
...
//Add CORS middleware before MVC
app.UseCors("AllowAll");
app.UseMvc(...);
}
Otherwise the request will be finished before the CORS middleware is applied. This is because UseMvc calls UseRouter which ends up adding the RouterMiddleware, and this middleware only executes the next configured middleware when a route handler wasn't found for the request.
In .Net Core Web API 5.0 in Configure method you have to add app.UseCors before other methods, like that:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
...
}
//add CORS
app.UseCors();
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}