Search code examples
c#dependency-injectioninvalidoperationexception

InvalidOperationException: Unable to resolve service for type 'R4.Services.TaskService' while attempting to activate 'R4.Services.CustomerService'


I generated a C#-Client with nswag studio. Now I'm calling a function of this client, that sets the tasks of a customer to done, if the customer is deleted.

If I call this function I will always run into this error message:

InvalidOperationException: Unable to resolve service for type 'R4.Services.TaskService' while attempting to activate 'R4.Services.CustomerService'.

I've already looked for ways to solve it and I know the error's reason, but I don't know how I can solve it. No post or page has helped me to solve it.

This is my code:

The configure-function to register the class in the DI-Container:

public static void Configure(IServiceCollection services, IConfiguration configuration)
{
            services.AddScoped<IBaseService<Task>, TaskService>();
            services.AddScoped<IBaseService<Customer>, CustomerService>();
}

This is the Customer-Service class:

public class CustomerService: BaseService<Customer>
{
   private readonly TaskService _taskService;
   public CustomerService(TaskService taskService){
      _taskService = taskService;
   }
}

Solution

  • If you look at this line

     public CustomerService(TaskService taskService)
    

    Then CustomerService wants to use the service of type TaskService

    if we then look at your configure method we see:

    services.AddScoped<IBaseService<Task>, TaskService>();
    

    The documentation states that this is

    AddScoped<TService, TImplementation>(IServiceCollection)

    So you see that the first definition is the TServicewhich you have defined as IBaseService<Task> .

    But, in your configure method you don't have any definitions of the type TaskService which your class is expecting. You have instead IBaseService<Task>. And in your class you have instead defined that the class should receive the Implementation (TaskService).

    So then you have several options:

    Change your class to be

    public CustomerService(IBaseService<Task> taskService)
    {
        _taskService = taskService as TaskService;
    }
    

    or maybe a better approach might be:

    Create a new Service

    public class ITaskService: IBaseService<Task> {} ....
    

    then change TaskService to implement ITaskService

    public class TaskService: ITaskService ....
    

    then define in your configure method

    services.AddScoped<ITaskService, TaskService>();
    

    and your class definition to use ITaskService

    private readonly ITaskService _taskService;
       public CustomerService(ITaskService taskService){
          _taskService = taskService;
       }
    

    That way, you could also have more services which inherit from IBaseService in the future, if needed.