Search code examples
c#asp.net-coreweb-applicationsdotnet-httpclientself-hosting

How to create ASP.NET Core host and run a request to it in the same process


How can I host ASP.NET Core web application and run requests against it? I tried this but apparently Thread.Sleep(1000); is not a way to go.

var builder = WebApplication.CreateBuilder();
builder.Services.AddControllers();

var app = builder.Build();

app.Urls.Add(BaseAddress);
app.UseRouting();

app.MapControllers().AddApplicationPart(assemblyUnderTest);

Task.Run(() => app.Run());

Thread.Sleep(1000); // better solution needed.

var client = new HttpClient();
var response = client.GetAsync(BaseAddress + "/subpath/key").Result;
Console.WriteLine(response);
Console.WriteLine(response.Content.ReadAsStringAsync().Result);

Solution

  • As I've indicated in the comments section there is a hook called ApplicationStarted which is exposed through the IHostApplicationLifetime. This hook is a CancellationToken so, you can use the Register function to execute a custom code when it signals. Unfortunately it does not support asynchronous code.

    Here is a working example how to issue a request against the application after it has been started:

    using Microsoft.AspNetCore.Hosting.Server;
    using Microsoft.AspNetCore.Hosting.Server.Features;
    
    var builder = WebApplication.CreateBuilder();
    var app = builder.Build();
    app.MapGet("/test", () => "Test");
    
    Task.Run(() => app.Run());
    
    IHostApplicationLifetime lifetime = app.Lifetime;
    lifetime.ApplicationStarted.Register(() =>
    {
        var server = app.Services.GetService<IServer>();
        var addressesFeature = server?.Features.Get<IServerAddressesFeature>();
        var baseAddress = addressesFeature?.Addresses.FirstOrDefault(); 
        
        var client = new HttpClient();
        var response = client.GetAsync($"{baseAddress}/test").Result;
        Console.WriteLine(response.Content.ReadAsStringAsync().Result); //Test
    });
    
    Console.ReadLine();
    

    Here is a working dotnet fiddle. Please note the This is only required in dotnet fiddle comment.