gpt4 book ai didi

c# - 如何使用 WebApplicationFactory 在 TestServer 中切换服务?

转载 作者:行者123 更新时间:2023-12-04 02:48:43 24 4
gpt4 key购买 nike

我正在使用自定义 WebApplication 工厂

public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<TStartup> where TStartup: class {
protected override void ConfigureWebHost(IWebHostBuilder builder) {
builder.ConfigureServices(services => {
// Create a new service provider.
var serviceProvider = new ServiceCollection()
.AddEntityFrameworkInMemoryDatabase()
.BuildServiceProvider();

services.AddDbContext<GrabGoContext>(options => {
options.UseInMemoryDatabase("GrabGoDb");
options.UseInternalServiceProvider(serviceProvider);
});

services.AddSingleton<TestEmailServer>();
services.AddScoped<IEmailProvider, TestEmailProvider>(); // <- HERE
});
base.ConfigureWebHost(builder);
}

我想切换我的默认 IEmailProvider服务调用 DefaultEmailProvider给我的特别 TestEmailProvider ,但问题在于方法 ConfigureWebHostStartup.ConfigureServices(IServiceCollection services) 之前执行,所以我的服务 DefaultEmailProvider设置在 TestEmailProvider 之后.因此在我的 ClientController服务 DeafultEmailProvider用于代替测试服务。

我的问题是:

如何切换服务 DefaultEmailProvider和我的 TestEmailProvider使用 WebApplicationFactory?

@更新

好的,我已经设法更深入了。我找到了那个方法 builder.ConfigureTestServices()覆盖其他服务。但是当在我的 ConfigureWebHost(IWebHostBuilder builder) 中切换时方法,我尝试使用 CreateClient() 创建新的 HttpClient|它抛出:
System.InvalidOperationException: 'A ConfigureServices method that returns an IServiceProvider is not compatible with the use of one or more IStartupConfigureServicesFilter. Use a void returning ConfigureServices method instead or a ConfigureContainer method.'

@更新 28.05.2019

仍在寻找更好的解决方案 ,但我已经设法做一些黑客。

在我的 Startup.cs我换了我的
services.AddScoped<IEmailProvider, SendGridEmailProvider>();
使用 TryAdd[Something]
services.TryAddScoped<IEmailProvider, SendGridEmailProvider>();

最佳答案

您应该能够在类似于以下内容的 ConfigureWebHost 中执行此操作:

public class CustomWebApplicationFactory : WebApplicationFactory<Startup>
{
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.ConfigureServices(services =>
{
// Remove application IEmailProvider service
var emailProviderDescriptor = services.SingleOrDefault(d => d.ServiceType == typeof(IEmailProvider));
if (emailProviderDescriptor != null)
{
services.Remove(emailProviderDescriptor);
}

// Add new test service(s)
services.AddScoped<IEmailProvider, TestEmailProvider>();
services.AddSingleton<TestEmailServer>(); // May need to remove using the descriptor similar to IEmailProvider

// Remove the app's GrabGoContext registration, add in memory one then seed data.
var dbDescriptor = services.SingleOrDefault(d => d.ServiceType == typeof(DbContextOptions<GrabGoContext>));
if (dbDescriptor != null)
{
services.Remove(dbDescriptor);
}

services.AddDbContext<GrabGoContext>(options =>
{
options.UseInMemoryDatabase("InMemoryDbForTesting");
});

var serviceProvider = services.BuildServiceProvider();
using var scope = serviceProvider.CreateScope();
var scopedServices = scope.ServiceProvider;
var grabGoContext = scopedServices.GetRequiredService<GrabGoContext>();

// Seed your db here & save..
grabGoContext.SaveChanges();
});

base.ConfigureWebHost(builder);
}
}

您可能想让自己更轻松,只需实现工厂,就像上面一样,而不是保持通用。我还为您的内存数据库添加了稍微不同的代码。

它尚未编译,但语法应该不远。
希望有帮助。

关于c# - 如何使用 WebApplicationFactory 在 TestServer 中切换服务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56060855/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com