aspnetcore/test/Microsoft.Extensions.Hostin.../HostBuilderTests.cs

476 lines
17 KiB
C#

// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Hosting.Fakes;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Xunit;
namespace Microsoft.Extensions.Hosting
{
public class HostBuilderTests
{
[Fact]
public void ConfigureHostConfigurationPropagated()
{
var host = new HostBuilder()
.ConfigureHostConfiguration(configBuilder =>
{
configBuilder.AddInMemoryCollection(new[]
{
new KeyValuePair<string, string>("key1", "value1")
});
})
.ConfigureHostConfiguration(configBuilder =>
{
configBuilder.AddInMemoryCollection(new[]
{
new KeyValuePair<string, string>("key2", "value2")
});
})
.ConfigureHostConfiguration(configBuilder =>
{
configBuilder.AddInMemoryCollection(new[]
{
// Hides value2
new KeyValuePair<string, string>("key2", "value3")
});
})
.ConfigureAppConfiguration((context, configBuilder) =>
{
Assert.Equal("value1", context.Configuration["key1"]);
Assert.Equal("value3", context.Configuration["key2"]);
var config = configBuilder.Build();
Assert.Equal("value1", config["key1"]);
Assert.Equal("value3", config["key2"]);
})
.Build();
using (host)
{
var config = host.Services.GetRequiredService<IConfiguration>();
Assert.Equal("value1", config["key1"]);
Assert.Equal("value3", config["key2"]);
}
}
[Fact]
public void CanConfigureAppConfigurationAndRetrieveFromDI()
{
var hostBuilder = new HostBuilder()
.ConfigureAppConfiguration((configBuilder) =>
{
configBuilder.AddInMemoryCollection(
new KeyValuePair<string, string>[]
{
new KeyValuePair<string, string>("key1", "value1")
});
})
.ConfigureAppConfiguration((configBuilder) =>
{
configBuilder.AddInMemoryCollection(
new KeyValuePair<string, string>[]
{
new KeyValuePair<string, string>("key2", "value2")
});
})
.ConfigureAppConfiguration((configBuilder) =>
{
configBuilder.AddInMemoryCollection(
new KeyValuePair<string, string>[]
{
// Hides value2
new KeyValuePair<string, string>("key2", "value3")
});
});
using (var host = hostBuilder.Build())
{
var config = host.Services.GetService<IConfiguration>();
Assert.NotNull(config);
Assert.Equal("value1", config["key1"]);
Assert.Equal("value3", config["key2"]);
}
}
[Fact]
public void DefaultIHostingEnvironmentValues()
{
var hostBuilder = new HostBuilder()
.ConfigureAppConfiguration((hostContext, appConfig) =>
{
var env = hostContext.HostingEnvironment;
Assert.Equal(EnvironmentName.Production, env.EnvironmentName);
Assert.Null(env.ApplicationName);
Assert.Equal(AppContext.BaseDirectory, env.ContentRootPath);
Assert.IsAssignableFrom<PhysicalFileProvider>(env.ContentRootFileProvider);
});
using (var host = hostBuilder.Build())
{
var env = host.Services.GetRequiredService<IHostingEnvironment>();
Assert.Equal(EnvironmentName.Production, env.EnvironmentName);
Assert.Null(env.ApplicationName);
Assert.Equal(AppContext.BaseDirectory, env.ContentRootPath);
Assert.IsAssignableFrom<PhysicalFileProvider>(env.ContentRootFileProvider);
}
}
[Fact]
public void ConfigBasedSettingsConfigBasedOverride()
{
var settings = new Dictionary<string, string>
{
{ HostDefaults.EnvironmentKey, "EnvA" }
};
var config = new ConfigurationBuilder()
.AddInMemoryCollection(settings)
.Build();
var overrideSettings = new Dictionary<string, string>
{
{ HostDefaults.EnvironmentKey, "EnvB" }
};
var overrideConfig = new ConfigurationBuilder()
.AddInMemoryCollection(overrideSettings)
.Build();
var hostBuilder = new HostBuilder()
.ConfigureHostConfiguration(configBuilder => configBuilder.AddConfiguration(config))
.ConfigureHostConfiguration(configBuilder => configBuilder.AddConfiguration(overrideConfig));
using (var host = hostBuilder.Build())
{
Assert.Equal("EnvB", host.Services.GetRequiredService<IHostingEnvironment>().EnvironmentName);
}
}
[Fact]
public void UseEnvironmentIsNotOverriden()
{
var vals = new Dictionary<string, string>
{
{ "ENV", "Dev" },
};
var builder = new ConfigurationBuilder()
.AddInMemoryCollection(vals);
var config = builder.Build();
var expected = "MY_TEST_ENVIRONMENT";
using (var host = new HostBuilder()
.ConfigureHostConfiguration(configBuilder => configBuilder.AddConfiguration(config))
.UseEnvironment(expected)
.Build())
{
Assert.Equal(expected, host.Services.GetService<IHostingEnvironment>().EnvironmentName);
}
}
[Fact]
public void BuildAndDispose()
{
using (var host = new HostBuilder()
.Build()) { }
}
[Fact]
public void UseBasePathConfiguresBasePath()
{
var vals = new Dictionary<string, string>
{
{ "ENV", "Dev" },
};
var builder = new ConfigurationBuilder()
.AddInMemoryCollection(vals);
var config = builder.Build();
using (var host = new HostBuilder()
.ConfigureHostConfiguration(configBuilder => configBuilder.AddConfiguration(config))
.UseContentRoot("/")
.Build())
{
Assert.Equal("/", host.Services.GetService<IHostingEnvironment>().ContentRootPath);
}
}
[Fact]
public void HostConfigParametersReadCorrectly()
{
var parameters = new Dictionary<string, string>()
{
{ "applicationName", "MyProjectReference"},
{ "environment", EnvironmentName.Development},
{ "contentRoot", Path.GetFullPath(".") }
};
var host = new HostBuilder()
.ConfigureHostConfiguration(config =>
{
config.AddInMemoryCollection(parameters);
}).Build();
var env = host.Services.GetRequiredService<IHostingEnvironment>();
Assert.Equal("MyProjectReference", env.ApplicationName);
Assert.Equal(EnvironmentName.Development, env.EnvironmentName);
Assert.Equal(Path.GetFullPath("."), env.ContentRootPath);
}
[Fact]
public void RelativeContentRootIsResolved()
{
using (var host = new HostBuilder()
.UseContentRoot("testroot")
.Build())
{
var basePath = host.Services.GetRequiredService<IHostingEnvironment>().ContentRootPath;
Assert.True(Path.IsPathRooted(basePath));
Assert.EndsWith(Path.DirectorySeparatorChar + "testroot", basePath);
}
}
[Fact]
public void DefaultContentRootIsApplicationBasePath()
{
using (var host = new HostBuilder()
.Build())
{
var appBase = AppContext.BaseDirectory;
Assert.Equal(appBase, host.Services.GetService<IHostingEnvironment>().ContentRootPath);
}
}
[Fact]
public void DefaultServicesAreAvailable()
{
using (var host = new HostBuilder()
.Build())
{
Assert.NotNull(host.Services.GetRequiredService<IHostingEnvironment>());
Assert.NotNull(host.Services.GetRequiredService<IConfiguration>());
Assert.NotNull(host.Services.GetRequiredService<HostBuilderContext>());
Assert.NotNull(host.Services.GetRequiredService<IApplicationLifetime>());
Assert.NotNull(host.Services.GetRequiredService<ILoggerFactory>());
Assert.NotNull(host.Services.GetRequiredService<IOptions<FakeOptions>>());
}
}
[Fact]
public void DefaultCreatesLoggerFactory()
{
var hostBuilder = new HostBuilder();
using (var host = hostBuilder.Build())
{
Assert.NotNull(host.Services.GetService<ILoggerFactory>());
}
}
[Fact]
public void MultipleConfigureLoggingInvokedInOrder()
{
var callCount = 0; //Verify ordering
var hostBuilder = new HostBuilder()
.ConfigureLogging((hostContext, loggerFactory) =>
{
Assert.Equal(0, callCount++);
})
.ConfigureLogging((hostContext, loggerFactory) =>
{
Assert.Equal(1, callCount++);
});
using (hostBuilder.Build())
{
Assert.Equal(2, callCount);
}
}
[Fact]
public void HostingContextContainsAppConfigurationDuringConfigureServices()
{
var hostBuilder = new HostBuilder()
.ConfigureAppConfiguration((configBuilder) =>
configBuilder.AddInMemoryCollection(
new KeyValuePair<string, string>[]
{
new KeyValuePair<string, string>("key1", "value1")
}))
.ConfigureServices((context, factory) =>
{
Assert.Equal("value1", context.Configuration["key1"]);
});
using (hostBuilder.Build()) { }
}
[Fact]
public void ConfigureDefaultServiceProvider()
{
var hostBuilder = new HostBuilder()
.ConfigureServices((s) =>
{
s.AddTransient<ServiceD>();
s.AddScoped<ServiceC>();
})
.UseServiceProviderFactory(new DefaultServiceProviderFactory(new ServiceProviderOptions()
{
ValidateScopes = true,
}));
var host = hostBuilder.Build();
Assert.Throws<InvalidOperationException>(() => { host.Services.GetRequiredService<ServiceC>(); });
}
[Fact]
public void ConfigureCustomServiceProvider()
{
var hostBuilder = new HostBuilder()
.ConfigureServices((hostContext, s) =>
{
s.AddTransient<ServiceD>();
s.AddScoped<ServiceC>();
})
.UseServiceProviderFactory(new FakeServiceProviderFactory())
.ConfigureContainer<FakeServiceCollection>((container) =>
{
Assert.Null(container.State);
container.State = "1";
})
.ConfigureContainer<FakeServiceCollection>((container) =>
{
Assert.Equal("1", container.State);
container.State = "2";
});
var host = hostBuilder.Build();
var fakeServices = host.Services.GetRequiredService<FakeServiceCollection>();
Assert.Equal("2", fakeServices.State);
}
[Fact]
public void CustomContainerTypeMismatchThrows()
{
var hostBuilder = new HostBuilder()
.ConfigureServices((s) =>
{
s.AddTransient<ServiceD>();
s.AddScoped<ServiceC>();
})
.UseServiceProviderFactory(new FakeServiceProviderFactory())
.ConfigureContainer<IServiceCollection>((container) =>
{
});
Assert.Throws<InvalidCastException>(() => hostBuilder.Build());
}
[Fact]
public void HostingContextContainsAppConfigurationDuringConfigureLogging()
{
var hostBuilder = new HostBuilder()
.ConfigureAppConfiguration((configBuilder) =>
configBuilder.AddInMemoryCollection(
new KeyValuePair<string, string>[]
{
new KeyValuePair<string, string>("key1", "value1")
}))
.ConfigureLogging((context, factory) =>
{
Assert.Equal("value1", context.Configuration["key1"]);
});
using (hostBuilder.Build()) { }
}
[Fact]
public void ConfigureServices_CanBeCalledMultipleTimes()
{
var callCount = 0; // Verify ordering
var hostBuilder = new HostBuilder()
.ConfigureServices((services) =>
{
Assert.Equal(0, callCount++);
services.AddTransient<ServiceA>();
})
.ConfigureServices((services) =>
{
Assert.Equal(1, callCount++);
services.AddTransient<ServiceB>();
});
using (var host = hostBuilder.Build())
{
Assert.Equal(2, callCount);
Assert.NotNull(host.Services.GetRequiredService<ServiceA>());
Assert.NotNull(host.Services.GetRequiredService<ServiceB>());
}
}
[Fact]
public void Build_DoesNotAllowBuildingMuiltipleTimes()
{
var builder = new HostBuilder();
using (builder.Build())
{
var ex = Assert.Throws<InvalidOperationException>(() => builder.Build());
Assert.Equal("Build can only be called once.", ex.Message);
}
}
[Fact]
public void SetsFullPathToContentRoot()
{
var host = new HostBuilder()
.ConfigureHostConfiguration(config =>
{
config.AddInMemoryCollection(new[]
{
new KeyValuePair<string, string>(HostDefaults.ContentRootKey, Path.GetFullPath("."))
});
})
.Build();
var env = host.Services.GetRequiredService<IHostingEnvironment>();
Assert.Equal(Path.GetFullPath("."), env.ContentRootPath);
Assert.IsAssignableFrom<PhysicalFileProvider>(env.ContentRootFileProvider);
}
[Fact]
public void BuilderPropertiesAreAvailableInBuilderAndContext()
{
var hostBuilder = new HostBuilder()
.ConfigureServices((hostContext, services) =>
{
Assert.Equal("value", hostContext.Properties["key"]);
});
hostBuilder.Properties.Add("key", "value");
Assert.Equal("value", hostBuilder.Properties["key"]);
using (hostBuilder.Build()) { }
}
private class ServiceC
{
public ServiceC(ServiceD serviceD) { }
}
internal class ServiceD { }
internal class ServiceA { }
internal class ServiceB { }
}
}