Dependency Injection plays a crucial role in building maintainable applications in .NET Core. It helps in building loosely coupled services that are scalable and less prone to bugs in the long run. However, sometimes we might encounter the error message “Unable to Resolve Service for Type While Attempting to Activate…” which can be frustrating and might hinder our progress.
In this article, we will explain what the error means, the different scenarios that might cause it, and how to fix each one of them.
Let’s get started.
Unable to Resolve a Service for a Type
When we encounter the error where our program is unable to resolve a service for a certain type X while attempting to activate another type Y, it means that the dependency injection container could not find a registered service for the specified type X.
This usually can occur for two reasons, we either didn’t register the service correctly in the dependency injection container or we are requesting a wrong type instance of the dependency.
Let’s see how to reproduce the errors and how to fix them.
Service Not Registered in the Dependency Injection Container
In our ASP.NET Web API project, let’s consider that we have a User
entity:
public class User { public int Id { get; set; } public string FirstName { get; set; } = string.Empty; public string LastName { get; set; } = string.Empty; }
In order to manipulate the User entity we create a IUserService
interface with a GetUser()
method:
public interface IUserService { User? GetUser(int id); }
Then, we implement the interface and for simplicity, we just return a hardcoded User
:
public class UserService : IUserService { public User GetUser() { return new User { Id = 1, FirstName = "Code", LastName = "Maze" }; } }
Finally, to be able to request a user from our server, we create a UserController
class that depends on IUserService
and contains a GetUser()
HTTP GET endpoint:
[Route("api/[controller]")] [ApiController] public class UserController : ControllerBase { private readonly IUserService _userService; public UserController(IUserService userService) { _userService = userService; } [HttpGet] public IActionResult GetUser() { var user = _userService.GetUser(); return Ok(user); } }
Once we try to run the code and call the GET endpoint, what we would expect from it is to return a 200 OK
response with the user details in the body. However, we get a 500 Internal Server Error
with an error message:
System.InvalidOperationException: Unable to resolve service for type 'FixUnableToResolveServiceIssue.Interfaces.IUserService' while attempting to activate 'FixUnableToResolveServiceIssue.Controllers.UserController'.
The reason behind this error is that the UserController
is requesting an implementation for the IUserService
interface from the dependency injection container but we did not register the UserService
nor any other implementation. Hence, the resolution of IUserService
has failed and we aren’t able to create or activate the UserController
.
Solution
To solve this issue we have to register the UserService
implementation of the IUserService
interface in the dependency injection container with the right lifetime, singleton, scoped, or transient. To do that, we need to add a single line of code in the Program.cs
file:
builder.Services.AddScoped<IUserService, UserService>();
Now, if we try to call the endpoint again we will get the expected response.
Injecting the Wrong Service in the Constructor
Sometimes, we register the service correctly in the dependency injection container but still get the same error. This might be caused by mistakenly injecting the wrong service into the constructor of the dependant.
Let’s update the UserController
‘s constructor and change IUserService
to UserService
:
[Route("api/[controller]")] [ApiController] public class UserController: ControllerBase { private readonly IUserService _userService; public UserController(UserService userService) { _userService = userService; } }
When we call the GetUser()
endpoint, we get:
System.InvalidOperationException: Unable to resolve service for type 'FixUnableToResolveServiceIssue.Services.UserService' while attempting to activate 'FixUnableToResolveServiceIssue.Controllers.UserController'.
If we look closely, we can see that we have requested the implementation UserService
instead of the IUserService
interface. And in our dependency injection container, we have only registered IUserService
.
Solution
To solve this issue, we should replace the constructor parameter type to be of the same type as the service registered in the dependency injection container.
In our case, we replace UserService
in the constructor of the UserController
with the interface IUserService
:
private readonly IUserService _userService; public UserController(IUserService userService) { _userService = userService; }
Conclusion
In this article, we discussed when our dependency injection is unable to resolve a service for a type while attempting to activate another type. We have seen that the error occurs when we don’t register the service in the dependency injection container or when we inject the wrong service in the constructor. By following the provided solutions, we can overcome this error to ensure the proper functioning of our applications.