I’m pretty sure it’s an error with DI, but I don’t know how to fix it.
using Microsoft.EntityFrameworkCore;
using RestApi.Models;
namespace RestApi.Services;
public class Builder
{
public static WebApplication Configurate(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("AppDb");
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// User defined
builder.Services.AddScoped<IUserService, UserService>();
builder.Services.AddScoped<IPassword, Password>();
builder.Services.AddDbContext<ApiContext>(x => x.UseSqlServer(connectionString));
return builder.Build();
}
}
using System.Security.Cryptography;
using Microsoft.AspNetCore.Cryptography.KeyDerivation;
namespace RestApi.Services;
public class Password : IPassword
{
public Password()
{
}
public string Hash(string password, byte[]? userSalt = null)
{
// Generate a 128-bit salt using a sequence of
// cryptographically strong random bytes.
byte[]? salt;
salt = userSalt ?? RandomNumberGenerator.GetBytes(128 / 8); // divide by 8 to convert bits to bytes
// derive a 256-bit subkey (use HMACSHA256 with 100,000 iterations)
var hashed = Convert.ToBase64String(KeyDerivation.Pbkdf2(
password: password!,
salt: salt,
prf: KeyDerivationPrf.HMACSHA256,
iterationCount: 100000,
numBytesRequested: 256 / 8));
return hashed;
}
public bool Validate(string password, byte[] salt, string correctPassword)
{
var hashed = Hash(password, salt);
if (hashed == correctPassword)
{
return true;
}
return false;
}
}
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using RestApi.Models;
namespace RestApi.Services;
public class UserService : IUserService
{
private readonly ApiContext _context;
private readonly Password _password;
public UserService(ApiContext context, Password password)
{
_context = context;
_password = password;
if (_context.Users == null)
throw new Exception();
}
public async Task<IEnumerable<UserModel>> All()
{
return await _context.Users.ToListAsync();
}
public async Task<ActionResult<UserModel>> Create(UserModel userModel)
{
userModel.Password = _password.Hash(userModel.Password);
_context.Users.Add(userModel);
await _context.SaveChangesAsync();
return new UserModel
{
Id = userModel.Id
};
}
public async Task<ActionResult<UserModel>> GetById(long id)
{
var userModel = await _context.Users.FindAsync(id);
if (userModel == null)
return null;
return userModel;
}
public async Task<bool> Delete(long id)
{
var userModel = await _context.Users.FindAsync(id);
if (userModel == null)
return false;
_context.Users.Remove(userModel);
await _context.SaveChangesAsync();
return true;
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using RestApi.Models;
using RestApi.Services;
namespace RestApi.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class UsersController : ControllerBase
{
private readonly IUserService _userService;
public UsersController(IUserService userService)
{
_userService = userService;
}
// GET: api/Users
[HttpGet]
public async Task<IEnumerable<UserModel>> GetUsers()
{
return await _userService.All();
}
// POST: api/Users
// To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
[HttpPost]
public async Task<ActionResult<UserModel>> PostUserModel(UserModel userModel)
{
return CreatedAtAction("GetUserModel", await _userService.Create(userModel), userModel);
}
// GET: api/Users/5
[HttpGet("{id}")]
public async Task<ActionResult<UserModel>> GetUserModel(long id)
{
ActionResult<UserModel> user = await _userService.GetById(id);
if (user == null)
{
return NotFound();
}
return user;
}
// DELETE: api/Users/5
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteUserModel(long id)
{
if (!await _userService.Delete(id))
return NotFound();
return Ok();
}
/*// PUT: api/Users/5
// To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
[HttpPut("{id}")]
public async Task<IActionResult> PutUserModel(long id, UserModel userModel)
{
if (id != userModel.Id)
{
return BadRequest();
}
_context.Entry(userModel).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!UserModelExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return NoContent();
}
private bool UserModelExists(long id)
{
return (_context.Users?.Any(e => e.Id == id)).GetValueOrDefault();
}*/
}
}
An error occurred while starting the application:
AggregateException: Some services are not able to be constructed (Error while validating the service descriptor ‘ServiceType: RestApi.Services.IUserService Lifetime: Scoped ImplementationType: RestApi.Services.UserService’: Unable to resolve service for type ‘RestApi.Services.Password’ while attempting to activate ‘RestApi.Services.UserService’.)
Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor(ICollection serviceDescriptors, ServiceProviderOptions options)
InvalidOperationException: Error while validating the service descriptor ‘ServiceType: RestApi.Services.IUserService Lifetime: Scoped ImplementationType: RestApi.Services.UserService’: Unable to resolve service for type ‘RestApi.Services.Password’ while attempting to activate ‘RestApi.Services.UserService’.
Microsoft.Extensions.DependencyInjection.ServiceProvider.ValidateService(ServiceDescriptor descriptor)
AggregateException: Some services are not able to be constructed (Error while validating the service descriptor ‘ServiceType: RestApi.Services.IUserService Lifetime: Scoped ImplementationType: RestApi.Services.UserService’: Unable to resolve service for type ‘RestApi.Services.Password’ while attempting to activate ‘RestApi.Services.UserService’.)
I am trying to inject the dependencies and start the program
>Solution :
You injected the IPassword interface but used the Password class in UserService instead of the interface.
change your UserService class to this
public UserService(ApiContext context, IPassword password)
{
_context = context;
_password = password;
if (_context.Users == null)
throw new Exception();
}