❔ Simple Api Fails to launch, why?

My Code:
uilder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddScoped<IRecordService, RecordService>();
builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("defaultConnection")));

var app = builder.Build();
uilder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddScoped<IRecordService, RecordService>();
builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("defaultConnection")));

var app = builder.Build();
My Error:
System.AggregateException: 'Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: Services.Interfaces.IRecordService Lifetime: Scoped ImplementationType: Services.Services.RecordService': Unable to resolve service for type 'Core.Interfaces.IRecordRepository' while attempting to activate 'Services.Services.RecordService'.)'
System.AggregateException: 'Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: Services.Interfaces.IRecordService Lifetime: Scoped ImplementationType: Services.Services.RecordService': Unable to resolve service for type 'Core.Interfaces.IRecordRepository' while attempting to activate 'Services.Services.RecordService'.)'
How do i fix this? whats the prblem?
46 Replies
BananaPie
BananaPie2y ago
did you bind "IRecordRepository"? Unable to resolve service for type 'Core.Interfaces.IRecordRepository' while attempting to activate 'Services.Services.RecordService'
Angius
Angius2y ago
Yeah, RecordService has RecordRepository as a dependency, but the latter is nowhere in the DI
antimatter8189
hmm, can u elaborate?
Angius
Angius2y ago
Your record service needs a record repository But has nowhere to take it from Everything you want injectable you need to register first
antimatter8189
how would u go about fixing it?
Angius
Angius2y ago
Register the repository
antimatter8189
how do i make it take it from somwehre builder.Services.AddScoped<IRecordRepository, RecordRepository>(); ?
Angius
Angius2y ago
Yep For example
antimatter8189
so this:
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(); builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("defaultConnection")));
builder.Services.AddScoped<IRecordRepository, RecordRepository>();
builder.Services.AddScoped<IRecordService, RecordService>();
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(); builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("defaultConnection")));
builder.Services.AddScoped<IRecordRepository, RecordRepository>();
builder.Services.AddScoped<IRecordService, RecordService>();
gives the same error why? wth is going on
Angius
Angius2y ago
Show your RecordService ig
antimatter8189
public class RecordService : IRecordService
{
private readonly IRecordRepository _recordRepository;
private readonly IUnitOfWork _unitOfWork;

public RecordService(IRecordRepository recordRepository, IUnitOfWork unitOfWork)
{
_recordRepository = recordRepository;
_unitOfWork = unitOfWork;
}

public async Task<Record> AddRecordAsync(Record record)
{
try
{
await _recordRepository.AddAsync(record);
await _unitOfWork.SaveAsync();
return record;
}
catch (Exception)
{
throw;
}
}

public async Task<Record> UpdateRecordAsync(Record record)
{
try
{
await _recordRepository.UpdateAsync(record);
await _unitOfWork.SaveAsync();
return record;
}
catch (Exception)
{
throw;
}
}

public async Task<bool> DeleteRecordAsync(Guid recordId)
{
try
{
var record = await _recordRepository.GetByIdAsync(recordId);
if (record == null)
{
return false;
}
await _recordRepository.DeleteAsync(record);
await _unitOfWork.SaveAsync();
return true;
}
catch (Exception)
{
return false;
}
}

public Task<Record> GetRecordByIdAsync(Guid recordId)
{
return _recordRepository.GetByIdAsync(recordId);
}

public Task<IEnumerable<Record>> GetAllRecordsAsync()
{
return _recordRepository.GetAllAsync();
}
}
public class RecordService : IRecordService
{
private readonly IRecordRepository _recordRepository;
private readonly IUnitOfWork _unitOfWork;

public RecordService(IRecordRepository recordRepository, IUnitOfWork unitOfWork)
{
_recordRepository = recordRepository;
_unitOfWork = unitOfWork;
}

public async Task<Record> AddRecordAsync(Record record)
{
try
{
await _recordRepository.AddAsync(record);
await _unitOfWork.SaveAsync();
return record;
}
catch (Exception)
{
throw;
}
}

public async Task<Record> UpdateRecordAsync(Record record)
{
try
{
await _recordRepository.UpdateAsync(record);
await _unitOfWork.SaveAsync();
return record;
}
catch (Exception)
{
throw;
}
}

public async Task<bool> DeleteRecordAsync(Guid recordId)
{
try
{
var record = await _recordRepository.GetByIdAsync(recordId);
if (record == null)
{
return false;
}
await _recordRepository.DeleteAsync(record);
await _unitOfWork.SaveAsync();
return true;
}
catch (Exception)
{
return false;
}
}

public Task<Record> GetRecordByIdAsync(Guid recordId)
{
return _recordRepository.GetByIdAsync(recordId);
}

public Task<IEnumerable<Record>> GetAllRecordsAsync()
{
return _recordRepository.GetAllAsync();
}
}
Angius
Angius2y ago
Huh, the code being very enterprise-y aside, it should work
antimatter8189
However it doesnt 😄 so,, im dead in the water? 😄
Angius
Angius2y ago
Uh, show your RecordRepository too...?
antimatter8189
using Core.Interfaces;
using Core.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace Infrastructure.Repositories
{
public class RecordRepository : GenericRepository<Record>, IRecordRepository
{
public RecordRepository(ApplicationDbContext context) : base(context)
{
}

}
}
using Core.Interfaces;
using Core.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace Infrastructure.Repositories
{
public class RecordRepository : GenericRepository<Record>, IRecordRepository
{
public RecordRepository(ApplicationDbContext context) : base(context)
{
}

}
}
using Core.Interfaces;
using Core.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Infrastructure.Repositories
{
public class GenericRepository<T> : IRepository<T> where T : class
{
private readonly ApplicationDbContext _context;
private DbSet<T> _entities;

public GenericRepository(ApplicationDbContext context)
{
_context = context;
_entities = context.Set<T>();
}

public async Task<T> GetByIdAsync(Guid id) => await _entities.FindAsync(id);

public async Task<T> AddAsync(T entity)
{
await _entities.AddAsync(entity);
await _context.SaveChangesAsync();
return entity;
}

public async Task<IEnumerable<T>> GetAllAsync()
{
var entityType = typeof(T);

if (entityType.GetProperties().Any(p => p.Name == "IsDeleted"))
{
return await _entities.Where(e => !(bool)entityType.GetProperty("IsDeleted")
.GetValue(e)).ToListAsync();
}
else
{
return await _entities.ToListAsync();
}
}

public async Task<T> UpdateAsync(T entity)
{
_entities.Update(entity);
await _context.SaveChangesAsync();
return entity;
}

public async Task DeleteAsync(T entity)
{
_entities.Remove(entity);
await _context.SaveChangesAsync();
}

public async Task SaveAsync()
{
await _context.SaveChangesAsync();
}
}
}
using Core.Interfaces;
using Core.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Infrastructure.Repositories
{
public class GenericRepository<T> : IRepository<T> where T : class
{
private readonly ApplicationDbContext _context;
private DbSet<T> _entities;

public GenericRepository(ApplicationDbContext context)
{
_context = context;
_entities = context.Set<T>();
}

public async Task<T> GetByIdAsync(Guid id) => await _entities.FindAsync(id);

public async Task<T> AddAsync(T entity)
{
await _entities.AddAsync(entity);
await _context.SaveChangesAsync();
return entity;
}

public async Task<IEnumerable<T>> GetAllAsync()
{
var entityType = typeof(T);

if (entityType.GetProperties().Any(p => p.Name == "IsDeleted"))
{
return await _entities.Where(e => !(bool)entityType.GetProperty("IsDeleted")
.GetValue(e)).ToListAsync();
}
else
{
return await _entities.ToListAsync();
}
}

public async Task<T> UpdateAsync(T entity)
{
_entities.Update(entity);
await _context.SaveChangesAsync();
return entity;
}

public async Task DeleteAsync(T entity)
{
_entities.Remove(entity);
await _context.SaveChangesAsync();
}

public async Task SaveAsync()
{
await _context.SaveChangesAsync();
}
}
}
Angius
Angius2y ago
Remove the ctor from your non-generic repo? It does nothing anyway
antimatter8189
Yeah It does
Angius
Angius2y ago
Not in the code you sent at least
antimatter8189
Cs7036 it breaks the build that piece of code is on all the code examples i saw
Angius
Angius2y ago
Ah, right, because it creates a default parameterless constructor...
antimatter8189
still the problem lingers
Angius
Angius2y ago
The problem is repositories over EF 😛
antimatter8189
System.AggregateException: 'Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: Services.Interfaces.IRecordService Lifetime: Scoped ImplementationType: Services.Services.RecordService': Unable to resolve service for type 'Core.Interfaces.IUnitOfWork' while attempting to activate 'Services.Services.RecordService'.)'
System.AggregateException: 'Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: Services.Interfaces.IRecordService Lifetime: Scoped ImplementationType: Services.Services.RecordService': Unable to resolve service for type 'Core.Interfaces.IUnitOfWork' while attempting to activate 'Services.Services.RecordService'.)'
nah that aint correct
Angius
Angius2y ago
You don't seem to have IUnitOfWork registered
antimatter8189
ms offican l
Angius
Angius2y ago
Angius
Angius2y ago
antimatter8189
builder.Services.AddScoped<IUnitOfWork, UnitOfWork>(); CORRECT now
Angius
Angius2y ago
DbContext is unit of work, DbSet<T> is a repository
antimatter8189
tell me why?
MODiX
MODiX2y ago
Angius#1586
DbContext is unit of work, DbSet<T> is a repository
Quoted by
React with ❌ to remove this embed.
antimatter8189
explain to me why this line: builder.Services.AddScoped<IUnitOfWork, UnitOfWork>(); make this work? i dont get it
Angius
Angius2y ago
Angius
Angius2y ago
Because you're injecting it
antimatter8189
it made swagger paunch
Angius
Angius2y ago
But from where?
antimatter8189
launch
Angius
Angius2y ago
As I said, anything you want injected, must be registered first You were injecting IUnitOFWork but it wasn't registered anywhere You told ASP "gimme the apple from the basket", but the basket had only carrots and motor oil
antimatter8189
Does it have to be in this order for it to work?
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(); builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("defaultConnection")));
builder.Services.AddScoped<IUnitOfWork, UnitOfWork>();
builder.Services.AddScoped<IRecordService, RecordService>();
builder.Services.AddScoped<IRecordRepository, RecordRepository>();
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(); builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("defaultConnection")));
builder.Services.AddScoped<IUnitOfWork, UnitOfWork>();
builder.Services.AddScoped<IRecordService, RecordService>();
builder.Services.AddScoped<IRecordRepository, RecordRepository>();
does the order matter?
Angius
Angius2y ago
Order doesn't matter, not in this case at least In some edge cases it might, but 99% of the time it doesn't
antimatter8189
Gotcha so every stuff i inject anywhere must be registered first then it can be injected got u correct?
Angius
Angius2y ago
Yep
antimatter8189
kk thx u a life saver 😄 gn thank alot!
Angius
Angius2y ago
Anytime 👌
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.