Skip to content
On this page

TIP

There is the new ConfigureTestServices() method in ASP.Net Core 5 that purports to do the same thing, but the Lamar team believes that the mechanism shown here will be more "correct" and also allows you to use Lamar specific features.

A new feature in Lamar v5.1 is a long requested way to reliably override service registrations in .Net Core applications bootstrapped by the generic host builder.

Let's say that in test automation scenarios you'd like to override some of the services in your normal application with testing stubs or to overwrite some kind of configuration. What you need to do is to take the IHostBuilder or IWebHostBuilder just as it is built by your application's bootstrapping, but apply service registrations that take precedence in Lamar over other registrations. That's a little trickier than you might think because the HostBuilder / WebHostBuilder applies service registrations in different places during bootstrapping, with registrations from Startup.ConfigureServices() taking precedence in normal usage.

That's where the new OverrideServices() extension method comes into play. As an example, let's say that in a test harness we want to just replace the normal ASP.Net Core IServer service with a fake implementation called FakeServer. The following is the code to do exactly that:

cs
[Fact]
public void sample_usage_of_overrides()
{
    var builder = Program
        .CreateHostBuilder(Array.Empty<string>())

        // This is our chance to make service overrides
        .OverrideServices(s => { s.For<IServer>().Use<FakeServer>(); });

    using var host = builder.Build();

    host.Services.GetRequiredService<IServer>()
        .ShouldBeOfType<FakeServer>();
}

snippet source | anchor

In the code above, the lambda passed into the OverrideServices() method is executed in the Lamar Container initialization after all other other explicit registrations and policies have been combined. In effect, this means that any registrations -- or removal of registrations -- in the OverrideServices() call are guaranteed to be processed last and reliably override any original registrations.

The OverrideServices() extension is only available for IHostBuilder.

If you are needing to create a test client or server to run integration tests you will need to use the ConfigWebHost() method of IHostBuilder to specifically create a test server, otherwise using host.GetTestServer() or host.GetTestClient() will throw a System.InvalidCastException. Additionally you'll want to use StartHost() rather than Build()

For example:

cs
[Fact]
public async Task sample_of_testing_with_client()
{
    // Arrange
    var builder = Program.CreateHostBuilder(Array.Empty<string>())
        // Make service overrides
        .OverrideServices(s => {
             s.For<IServer>().Use<FakeServer>();
        })
        .ConfigureWebHost(webHost =>
        {
            // Add TestServer
            webHost.UseTestServer();
        });
     
     
    // Start the test server
    var host = await builder.StartAsync();
    // Get a test client and do anything you need here like adding headers
    var client = host.GetTestClient();

    // Act
    var response = await client.GetAsync("api/controller/action");
    var content = await response.Content.ReadAsStringAsync();

    // Assert
    Assert.Equal(result.StatusCode, StatusCodes.Status200OK);
}