After changing the signature of the function ConfigureServices
to be asynchronous (originally it was just a void synchronous function and the application worked perfectly fine), I get the following error:
Unable to find the required services. Please add all the required services by calling
IServiceCollection.AddAuthorization
inside the call toConfigureServices(...)
in the application startup code.
Below is the code of my ConfigureServices
function.
// This method gets called by the runtime. Use this method to add services to the container.
public async Task ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
// Create the necessary Cosmos DB infrastructure
await CreateDatabaseAsync();
await CreateContainerAsync();
}
ConfigureServices
is automatically called at runtime.
So if you want to call it in the Startup. cs , you have to create an object first and then call it. For other class to call the GetAll() , you need to specify IValueService as one of constructor's parameter, then in the constructor, you keep the IValueService instance in a local private property.
All I/O in ASP.NET Core is asynchronous. Servers implement the Stream interface, which has both synchronous and asynchronous overloads. The asynchronous ones should be preferred to avoid blocking thread pool threads.
NET Core C# we make use of async and await keywords to implement asynchronous programming. For any method to be asynchronous we have to add the async keyword in the method definition before the return type of the method. Also, it is general practice to add Async to the name of the method if that method is asynchronous.
The async and await keywords An asynchronous method is one that is marked with the async keyword in the method signature. It can contain one or more await statements. It should be noted that await is a unary operator — the operand to await is the name of the method that needs to be awaited.
You can't just change the signature, it needs to be void to be called by the framework.
Right now when you changed it to Task it means that the framework can't find it so it will not be called at all.
There's a GitHub issue regarding this here: https://github.com/dotnet/aspnetcore/issues/5897
It's quite tricky though...
There's no progress for 5.0 no, we don't know how to do this without blocking or breaking changes. It might be possible to run filters in 2 stages that never overlap.
Update based on your comment: If you want to run something async during startup, I usually do like this:
I create a interface like this:
public interface IStartupTask
{
Task Execute();
}
Then a sample implementation like this
public class CreateDatabaseStartupTask : IStartupTask
{
public async Task Execute()
{
// My logic here
// await CreateDatabaseAsync();
}
}
Then in my Program.cs
public static async Task Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
// Resolve the StartupTasks from the ServiceProvider
var startupTasks = host.Services.GetServices<IStartupTask>();
// Run the StartupTasks
foreach(var startupTask in startupTasks)
{
await startupTask.Execute();
}
await host.RunAsync();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
And my Startup
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IStartupTask, CreateDatabaseStartupTask>();
}
}
So the important things are:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With