Как переключать сервисы в TestServer с помощью WebApplicationFactory? - PullRequest
1 голос
/ 09 мая 2019

Я использую пользовательскую фабрику веб-приложений

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, но проблема в том, что метод ConfigureWebHostвыполняется до Startup.ConfigureServices(IServiceCollection services), поэтому мой сервис DefaultEmailProvider устанавливается после TestEmailProvider.Поэтому в моем ClientController сервисе DeafultEmailProvider используется вместо тестового сервиса.

Мой вопрос:

Как я могу переключить сервис DefaultEmailProvider с моим TestEmailProvider, используя WebApplicationFactory?

@ Update

Хорошо, мне удалось углубиться.Я обнаружил, что метод builder.ConfigureTestServices() переопределяет другие службы.Но когда я переключаю это в моем методе ConfigureWebHost(IWebHostBuilder builder), и я пытаюсь создать новый HttpClient, используя CreateClient(), он выдает:

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.'

@ Update 28.05.2019

Все еще ищулучшее решение , но мне удается сделать что-то вроде взломать .

В моем Startup.cs я поменял свой

services.AddScoped<IEmailProvider, SendGridEmailProvider>();

с TryAdd [Something]

services.TryAddScoped<IEmailProvider, SendGridEmailProvider>();

1 Ответ

1 голос
/ 09 мая 2019

Вы можете сделать это на основе окружающей среды.Это всего лишь код, указывающий вам правильное направление.

  public IHostingEnvironment HostingEnvironment { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        if (HostingEnvironment.IsDevelopment())
        {
            services.AddTransient<ITestService, TestService>();
        }
        else
        {
            services.AddTransient<IRealService, RealService>();
        }

        // other services
    }

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...