File: AcceptanceTest.cs
Web Access
Project: src\test\Libraries\Microsoft.Extensions.DependencyInjection.AutoActivation.Tests\Microsoft.Extensions.DependencyInjection.AutoActivation.Tests.csproj (Microsoft.Extensions.DependencyInjection.AutoActivation.Tests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection.Test.Fakes;
using Microsoft.Extensions.DependencyInjection.Test.Helpers;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Hosting.Testing;
using Xunit;
 
namespace Microsoft.Extensions.DependencyInjection.Test;
 
public partial class AcceptanceTest
{
    [Fact]
    public async Task CanAddAndActivateSingletonAsync()
    {
        var instanceCount = new InstanceCreatingCounter();
        Assert.Equal(0, instanceCount.Counter);
 
        using var host = await FakeHost.CreateBuilder()
            .ConfigureServices(services => services
                .AddSingleton<IFakeServiceCounter>(instanceCount)
                .AddActivatedSingleton<IFakeService, FakeService>())
            .StartAsync();
 
        Assert.Equal(1, instanceCount.Counter);
 
        var service = host.Services.GetService<IFakeService>();
        await host.StopAsync();
 
        Assert.NotNull(service);
        Assert.Equal(1, instanceCount.Counter);
    }
 
    [Fact]
    public async Task ShouldIgnoreComponent_WhenNoAutoStartAsync()
    {
        var instanceCount = new InstanceCreatingCounter();
        Assert.Equal(0, instanceCount.Counter);
 
        using var host = await FakeHost.CreateBuilder()
            .ConfigureServices(services => services
                .AddSingleton<IFakeServiceCounter>(instanceCount)
                .AddSingleton<IFakeService, FakeService>())
            .StartAsync();
 
        Assert.Equal(0, instanceCount.Counter);
 
        var service = host.Services.GetService<IFakeService>();
        await host.StopAsync();
 
        Assert.NotNull(service);
        Assert.Equal(1, instanceCount.Counter);
    }
 
    [Fact]
    public async Task ShouldAddAndActivateOnlyOnce_WhenHasChildAsync()
    {
        var parentCount = new InstanceCreatingCounter();
        var childCount = new InstanceCreatingCounter();
 
        using var host = await FakeHost.CreateBuilder()
            .ConfigureServices(services => services.AddSingleton<IFakeServiceCounter>(childCount)
                .AddSingleton<IFactoryServiceCounter>(parentCount)
                .AddActivatedSingleton(typeof(IFakeService), typeof(FakeService))
                .AddActivatedSingleton<IFactoryService, FactoryService>(sp =>
                {
                    return new FactoryService(sp.GetService<IFakeService>()!, sp.GetService<IFactoryServiceCounter>()!);
                }))
            .StartAsync();
        await host.StopAsync();
 
        Assert.Equal(1, childCount.Counter);
        Assert.Equal(1, parentCount.Counter);
    }
 
    [Fact]
    public async Task ShouldResolveComponentsAutomaticallyAsync()
    {
        var parentCount = new InstanceCreatingCounter();
        var childCount = new InstanceCreatingCounter();
 
        using var host = await FakeHost.CreateBuilder()
            .ConfigureServices(services => services
                .AddSingleton<IFakeServiceCounter>(childCount)
                .AddSingleton<IFactoryServiceCounter>(parentCount)
                .AddSingleton<IFakeService, FakeService>()
                .AddActivatedSingleton<IFactoryService, FactoryService>())
            .StartAsync();
        await host.StopAsync();
 
        Assert.Equal(1, childCount.Counter);
        Assert.Equal(1, parentCount.Counter);
    }
 
    [Fact]
    public async Task CanActivateEnumerableAsync()
    {
        var fakeServiceCount = new InstanceCreatingCounter();
        var fakeFactoryCount = new InstanceCreatingCounter();
        var anotherFakeServiceCount = new AnotherFakeServiceCounter();
 
        using var host = await FakeHost.CreateBuilder()
            .ConfigureServices(services => services
                .AddSingleton<IFakeServiceCounter>(fakeServiceCount)
                .AddSingleton<IFakeMultipleCounter>(fakeFactoryCount)
                .AddSingleton<IAnotherFakeServiceCounter>(anotherFakeServiceCount)
                .AddActivatedSingleton(typeof(IFakeService), typeof(FakeService))
                .AddActivatedSingleton(typeof(IFakeService), typeof(FakeOneMultipleService))
                .AddActivatedSingleton(typeof(IFakeService), typeof(AnotherFakeService)))
            .StartAsync();
        await host.StopAsync();
 
        Assert.Equal(1, fakeServiceCount.Counter);
        Assert.Equal(1, fakeFactoryCount.Counter);
        Assert.Equal(1, anotherFakeServiceCount.Counter);
 
        await host.StopAsync();
    }
 
    [Fact]
    public async Task CanActivateEnumerableAsync_WithTypeArg()
    {
        var fakeServiceCount = new InstanceCreatingCounter();
        var fakeFactoryCount = new InstanceCreatingCounter();
        var anotherFakeServiceCount = new AnotherFakeServiceCounter();
 
        using var host = await FakeHost.CreateBuilder()
            .ConfigureServices(services => services
                .AddSingleton<IFakeServiceCounter>(fakeServiceCount)
                .AddSingleton<IFakeMultipleCounter>(fakeFactoryCount)
                .AddSingleton<IAnotherFakeServiceCounter>(anotherFakeServiceCount)
                .AddActivatedSingleton<IFakeService, FakeService>()
                .AddActivatedSingleton<IFakeService, FakeOneMultipleService>()
                .AddActivatedSingleton<IFakeService, AnotherFakeService>())
            .StartAsync();
        await host.StopAsync();
 
        Assert.Equal(1, fakeServiceCount.Counter);
        Assert.Equal(1, fakeFactoryCount.Counter);
        Assert.Equal(1, anotherFakeServiceCount.Counter);
 
        await host.StopAsync();
    }
 
    [Fact]
    public async Task CanActivateOneServiceAsync()
    {
        var fakeServiceCount = new InstanceCreatingCounter();
        var anotherFakeServiceCount = new AnotherFakeServiceCounter();
 
        using var host = await FakeHost.CreateBuilder()
            .ConfigureServices(services => services
                .AddSingleton<IFakeServiceCounter>(fakeServiceCount)
                .AddSingleton<IAnotherFakeServiceCounter>(anotherFakeServiceCount)
                .AddSingleton<IFakeService, FakeService>()
                .AddActivatedSingleton<IFakeService, AnotherFakeService>())
            .StartAsync();
        await host.StopAsync();
 
        Assert.Equal(0, fakeServiceCount.Counter);
        Assert.Equal(1, anotherFakeServiceCount.Counter);
    }
 
    [Fact]
    public async Task ShouldActivateService_WhenTypeIsSpecifiedInTypeParameterTService()
    {
        var counter = new InstanceCreatingCounter();
        var anotherFakeServiceCount = new AnotherFakeServiceCounter();
 
        using var host = await FakeHost.CreateBuilder()
            .ConfigureServices(services => services
                .AddSingleton<IFakeServiceCounter>(counter)
                .AddSingleton<IAnotherFakeServiceCounter>(anotherFakeServiceCount)
                .AddActivatedSingleton<FakeService>()
                .AddActivatedSingleton(sp => new AnotherFakeService(sp.GetService<IAnotherFakeServiceCounter>()!)))
            .StartAsync();
        await host.StopAsync();
 
        Assert.Equal(1, counter.Counter);
        Assert.Equal(1, anotherFakeServiceCount.Counter);
    }
 
    [Fact]
    public async Task ShouldActivateService_WhenTypeIsSpecifiedInParameter()
    {
        var counter = new InstanceCreatingCounter();
        var anotherFakeServiceCount = new AnotherFakeServiceCounter();
 
        using var host = await FakeHost.CreateBuilder()
            .ConfigureServices(services => services
                .AddSingleton<IFakeServiceCounter>(counter)
                .AddSingleton<IAnotherFakeServiceCounter>(anotherFakeServiceCount)
                .AddActivatedSingleton(typeof(FakeService))
                .AddActivatedSingleton(typeof(AnotherFakeService), sp => new AnotherFakeService(sp.GetService<IAnotherFakeServiceCounter>()!)))
            .StartAsync();
        await host.StopAsync();
 
        Assert.Equal(1, counter.Counter);
        Assert.Equal(1, anotherFakeServiceCount.Counter);
    }
 
    [Fact]
    public async Task TestStopHostAsync()
    {
        var counter = new InstanceCreatingCounter();
 
        using var host = await FakeHost.CreateBuilder()
            .ConfigureServices(services => services
                .AddSingleton<IFakeServiceCounter>(counter)
                .AddActivatedSingleton<IFakeService, FakeService>())
            .StartAsync();
 
        Assert.Equal(1, counter.Counter);
        await host.StopAsync();
    }
 
    [Fact]
    public async Task ShouldNotActivate_WhenServiceOfTypeSpecifiedInTypeParameter_WasAlreadyAdded()
    {
        var counter = new InstanceCreatingCounter();
        var anotherFakeServiceCount = new AnotherFakeServiceCounter();
 
        using var host = await FakeHost.CreateBuilder()
            .ConfigureServices(services =>
            {
                services
                    .AddSingleton<IFakeServiceCounter>(counter)
                    .AddSingleton<IAnotherFakeServiceCounter>(anotherFakeServiceCount)
                    .AddSingleton<FakeService>()
                    .AddSingleton<AnotherFakeService>();
                services.TryAddActivatedSingleton(typeof(FakeService));
                services.TryAddActivatedSingleton(typeof(AnotherFakeService), sp => new AnotherFakeService(sp.GetService<IAnotherFakeServiceCounter>()!));
            })
            .StartAsync();
        await host.StopAsync();
 
        Assert.Equal(0, counter.Counter);
        Assert.Equal(0, anotherFakeServiceCount.Counter);
    }
 
    [Fact]
    public async Task ShouldNotActivate_WhenServiceOfTypeSpecifiedInParameter_WasAlreadyAdded()
    {
        var counter = new InstanceCreatingCounter();
        var anotherFakeServiceCount = new AnotherFakeServiceCounter();
 
        using var host = await FakeHost.CreateBuilder()
            .ConfigureServices(services =>
            {
                services
                    .AddSingleton<IFakeServiceCounter>(counter)
                    .AddSingleton<IAnotherFakeServiceCounter>(anotherFakeServiceCount)
                    .AddSingleton<FakeService>()
                    .AddSingleton<AnotherFakeService>();
                services.TryAddActivatedSingleton<FakeService>();
                services.TryAddActivatedSingleton(sp => new AnotherFakeService(sp.GetService<IAnotherFakeServiceCounter>()!));
            })
            .StartAsync();
        await host.StopAsync();
 
        Assert.Equal(0, counter.Counter);
        Assert.Equal(0, anotherFakeServiceCount.Counter);
    }
 
    [Fact]
    public async Task ShouldActivateOneSingleton_WhenTryAddIsCalled_WithTypeSpecifiedImplementation()
    {
        var counter = new InstanceCreatingCounter();
        var anotherFakeServiceCount = new AnotherFakeServiceCounter();
 
        using var host = await FakeHost.CreateBuilder()
            .ConfigureServices(services =>
                {
                    services
                        .AddSingleton<IFakeServiceCounter>(counter)
                        .AddSingleton<IAnotherFakeServiceCounter>(anotherFakeServiceCount);
                    services.TryAddActivatedSingleton(typeof(IFakeService), typeof(FakeService));
                    services.TryAddActivatedSingleton(typeof(IFakeService), typeof(AnotherFakeService));
                })
            .StartAsync();
        await host.StopAsync();
 
        Assert.Equal(1, counter.Counter);
        Assert.Equal(0, anotherFakeServiceCount.Counter);
    }
 
    [Fact]
    public async Task ShouldActivateOneSingleton_WhenTryAddIsCalled_WithTypeSpecifiedImplementation_WithTypeArg()
    {
        var counter = new InstanceCreatingCounter();
        var anotherFakeServiceCount = new AnotherFakeServiceCounter();
 
        using var host = await FakeHost.CreateBuilder()
            .ConfigureServices(services =>
            {
                services
                    .AddSingleton<IFakeServiceCounter>(counter)
                    .AddSingleton<IAnotherFakeServiceCounter>(anotherFakeServiceCount);
                services.TryAddActivatedSingleton<IFakeService, FakeService>();
                services.TryAddActivatedSingleton<IFakeService, AnotherFakeService>();
            })
            .StartAsync();
        await host.StopAsync();
 
        Assert.Equal(1, counter.Counter);
        Assert.Equal(0, anotherFakeServiceCount.Counter);
    }
 
    [Fact]
    public async Task CanActivateSingletonAsync()
    {
        var instanceCount = new InstanceCreatingCounter();
        Assert.Equal(0, instanceCount.Counter);
 
        using var host = await FakeHost.CreateBuilder()
            .ConfigureServices(services => services
                .AddSingleton<IFakeServiceCounter>(instanceCount)
                .AddSingleton<IFakeService, FakeService>()
                .ActivateSingleton<IFakeService>())
            .StartAsync();
        await host.StopAsync();
 
        Assert.Equal(1, instanceCount.Counter);
 
        var service = host.Services.GetService<IFakeService>();
 
        Assert.NotNull(service);
        Assert.Equal(1, instanceCount.Counter);
    }
 
    [Fact]
    public async Task ActivationOfNotRegisteredType_ThrowsExceptionAsync()
    {
        using var host = FakeHost.CreateBuilder()
            .ConfigureServices(services => services.ActivateSingleton<IFakeService>())
            .Build();
 
        var exception = await Assert.ThrowsAsync<InvalidOperationException>(() => host.StartAsync());
 
        Assert.Contains(typeof(IFakeService).FullName!, exception.Message);
    }
 
    [Fact]
    public async Task CanActivateEnumerableImplicitlyAddedAsync()
    {
        var fakeServiceCount = new InstanceCreatingCounter();
        var fakeFactoryCount = new InstanceCreatingCounter();
 
        using var host = await FakeHost.CreateBuilder()
            .ConfigureServices(services => services
                .AddSingleton<IFakeServiceCounter>(fakeServiceCount)
                .AddSingleton<IFakeMultipleCounter>(fakeFactoryCount)
                .AddSingleton<IFakeService, FakeService>().ActivateSingleton(typeof(IFakeService))
                .AddSingleton<IFakeService, FakeOneMultipleService>().ActivateSingleton(typeof(IFakeService)))
            .StartAsync();
        await host.StopAsync();
 
        Assert.Equal(1, fakeServiceCount.Counter);
        Assert.Equal(1, fakeFactoryCount.Counter);
    }
 
    [Fact]
    public async Task CanActivateEnumerableImplicitlyAddedAsync_WithTypeArg()
    {
        var fakeServiceCount = new InstanceCreatingCounter();
        var fakeFactoryCount = new InstanceCreatingCounter();
 
        using var host = await FakeHost.CreateBuilder()
            .ConfigureServices(services => services
                .AddSingleton<IFakeServiceCounter>(fakeServiceCount)
                .AddSingleton<IFakeMultipleCounter>(fakeFactoryCount)
                .AddSingleton<IFakeService, FakeService>().ActivateSingleton<IFakeService>()
                .AddSingleton<IFakeService, FakeOneMultipleService>().ActivateSingleton<IFakeService>())
            .StartAsync();
        await host.StopAsync();
 
        Assert.Equal(1, fakeServiceCount.Counter);
        Assert.Equal(1, fakeFactoryCount.Counter);
    }
 
    [Fact]
    public async Task CanActivateEnumerableExplicitlyAddedAsync()
    {
        var fakeServiceCount = new InstanceCreatingCounter();
        var fakeFactoryCount = new InstanceCreatingCounter();
 
        using var host = await FakeHost.CreateBuilder()
            .ConfigureServices(services => services
                .AddSingleton<IFakeServiceCounter>(fakeServiceCount)
                .AddSingleton<IFakeMultipleCounter>(fakeFactoryCount)
                .AddSingleton<IFakeService, FakeService>()
                .AddSingleton<IFakeService, FakeOneMultipleService>()
                .ActivateSingleton<IEnumerable<IFakeService>>())
            .StartAsync();
        await host.StopAsync();
 
        Assert.Equal(1, fakeServiceCount.Counter);
        Assert.Equal(1, fakeFactoryCount.Counter);
    }
 
    [Fact]
    public async Task CanAutoActivateOpenGenericsAsEnumerableAsync()
    {
        var fakeServiceCount = new InstanceCreatingCounter();
        var fakeOpenGenericCount = new InstanceCreatingCounter();
 
        using var host = await new HostBuilder()
            .ConfigureServices(services => services
                .AddSingleton<IFakeServiceCounter>(fakeServiceCount)
                .AddSingleton<IFakeOpenGenericCounter>(fakeOpenGenericCount)
                .AddTransient<PocoClass, PocoClass>()
                .AddSingleton(typeof(IFakeOpenGenericService<PocoClass>), typeof(FakeService))
                .AddSingleton(typeof(IFakeOpenGenericService<>), typeof(FakeOpenGenericService<>))
                .ActivateSingleton<IEnumerable<IFakeOpenGenericService<PocoClass>>>()
                .ActivateSingleton<IFakeOpenGenericService<DifferentPocoClass>>())
            .StartAsync();
        await host.StopAsync();
 
        Assert.Equal(1, fakeServiceCount.Counter);
        Assert.Equal(2, fakeOpenGenericCount.Counter);
    }
 
    [Fact]
    public async Task CanAutoActivateClosedGenericsAsEnumerableAsync()
    {
        var fakeServiceCount = new InstanceCreatingCounter();
        var fakeOpenGenericCount = new InstanceCreatingCounter();
 
        using var host = await FakeHost.CreateBuilder()
            .ConfigureServices(services => services
                .AddSingleton<IFakeServiceCounter>(fakeServiceCount)
                .AddSingleton<IFakeOpenGenericCounter>(fakeOpenGenericCount)
                .AddTransient<PocoClass, PocoClass>()
                .AddSingleton(typeof(IFakeOpenGenericService<PocoClass>), typeof(FakeService))
                .AddSingleton<IFakeOpenGenericService<PocoClass>, FakeOpenGenericService<PocoClass>>()
                .ActivateSingleton<IEnumerable<IFakeOpenGenericService<PocoClass>>>())
            .StartAsync();
        await host.StopAsync();
 
        Assert.Equal(1, fakeServiceCount.Counter);
        Assert.Equal(1, fakeOpenGenericCount.Counter);
    }
}