1

I have a factory method set up to return two different implementations of IDeployApplicationService based on a string value.

I've tried a few permutations of .AddScoped() or .AddTransient() in Program.cs but not sure why this error keeps persisting.

My factory

public class DeployApplicationServiceFactory : IDeployApplicationServiceFactory
    {
        private readonly IServiceProvider serviceProvider;

        public DeployApplicationServiceFactory(IServiceProvider serviceProvider)
        {
            this.serviceProvider = serviceProvider;
        }

        public IDeployApplicationService GetService(string environment)
        {
            if (environment.ToLower() == "prod")
            {
                // Error thrown in the line below.
                // An exception of type 'System.InvalidOperationException' occurred 
                // in Microsoft.Extensions.DependencyInjection.Abstractions.dll 
                // but was not handled in user code: 'No service for type 
                // 'ProdDeployApplicationService' has been registered.'

                return serviceProvider.GetRequiredService<ProdDeployApplicationService>();
            }
            else
            {
                return serviceProvider.GetRequiredService<NonProdDeployApplicationService>();

            }
        }
    }

Program.cs (this is a worker)


public static IHostBuilder CreateHostBuilder(string[] args) =>

    Host.ConfigureServices((hostContext, services) =>
    {
         //[...]

         services.AddScoped<IDeployApplicationServiceFactory, DeployApplicationServiceFactory>();
         services.AddScoped<IDeployApplicationService, ProdDeployApplicationService>();
         services.AddScoped<IDeployApplicationService, NonProdDeployApplicationService>();

         //[...]
    }

1 Answer 1

2

You've registered the service by its interface:

services.AddScoped<IDeployApplicationService, ProdDeployApplicationService>()

This means you can only resolve it by the interface serviceProvider.GetRequiredService<IDeployApplicationService>(), and that would give you the last service registered by that interface, NonProdDeployApplicationService.

Try registering it by itself (the implementation):

services.AddScoped<ProdDeployApplicationService>();

Now you can resolve the implementation directly:

serviceProvider.GetRequiredService<ProdDeployApplicationService>();

Keep in mind you can register a class multiple times: both by itself and by the interfaces/abstract classes it implements:

// this is ok
services.AddScoped<ProdDeployApplicationService>();
services.AddScoped<IDeployService, ProdDeployApplicationService>();
services.AddScoped<IDeployApplicationService, ProdDeployApplicationService>();

and resolve it using any key.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.