Reputation: 325
I'm noob in netcore, i'm using generic repository and unit of work in netcore. but i'm having problems, my project is compose for 3 layers, Api, BLL, DA, i have this error. Unable to resolve service for type 'ProyectosInvestigacion.DAL.ProyectosInvestigacionContext' while attempting to activate 'ProyectosInvestigacion.DAL.Class.UnitOfWork'.
Thanks for you support
Project DA
IRepository
public interface IRepository<TEntity> where TEntity : class
{
IQueryable<TEntity> FindAll(string[] IncludeProperties = null);
IQueryable<TEntity> Find(Expression<Func<TEntity, bool>> predicate, string[] IncludeProperties = null);
TEntity FindById(int Id);
void Create(TEntity entity);
void Update(TEntity entity);
void Delete(TEntity entity);
void Delete(int Id);
}
Repository
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
{
private DbSet<TEntity> _DbSet;
private readonly ProyectosInvestigacionContext dbContext;
public Repository(ProyectosInvestigacionContext ProyectosInvestigacionContext)
{
this.dbContext = ProyectosInvestigacionContext;
this._DbSet = dbContext.Set<TEntity>();
}
/// <summary>
/// Add new entity
/// </summary>
/// <param name="entity">Entity to add </param>
public virtual void Create(TEntity entity)
{
_DbSet.Add(entity);
}
/// <summary>
/// Add new List of Entity
/// </summary>
/// <param name="entity"></param>
public virtual void Create(IEnumerable<TEntity> entity)
{
foreach (var item in entity)
{
_DbSet.Add(item);
}
} ....
IUnitOfWork
public interface IUnitOfWork : IDisposable
{
void SaveChanges();
IRepository<Grupo> GrupoRepository { get; }
}
UnitOfWork
public class UnitOfWork: IUnitOfWork
{
private readonly ProyectosInvestigacionContext dbContext;
private bool disposed;
private Dictionary<string, object> repositories;
private IRepository<Grupo> _grupoRepository;
///// <summary>
///// Constructor
///// </summary>
///// <param name="ProyectosInvestigacionContext">Context Class</param>
public UnitOfWork(ProyectosInvestigacionContext Context)
{
this.dbContext = Context;
}
/// <summary>
/// Execute pending changes
/// </summary>
public void SaveChanges()
{
dbContext.SaveChanges();
}
/// <summary>
/// Get Current Context
/// </summary>
/// <returns></returns>
public ProyectosInvestigacionContext GetContext()
{
return this.dbContext;
}
public IRepository<Grupo> GrupoRepository => _grupoRepository ??
(_grupoRepository = new Repository<Grupo>(dbContext));
/// <summary>
/// Disposing
/// </summary>
/// <param name="disposing">Bool to dispose</param>
public virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
dbContext.Dispose();
}
}
disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
ProyectosInvestigacionContext
public partial class ProyectosInvestigacionContext : DbContext
{
public ProyectosInvestigacionContext(DbContextOptions<ProyectosInvestigacionContext> options)
: base(options)
{
}
public virtual DbSet<Facultad> Facultad { get; set; }
public virtual DbSet<Grupo> Grupo { get; set; }
public virtual DbSet<GrupoPrograma> GrupoPrograma { get; set; } ....
Project BLL
GrupoBLL
public class GrupoBLL: IGrupo, IDisposable
{
private readonly IUnitOfWork UnitOfWork;
public GrupoBLL(IUnitOfWork UoW)
{
this.UnitOfWork = UoW;
}
public IEnumerable<Grupo> FindAll() {
return UnitOfWork.GrupoRepository.FindAll();
}
/// <summary>
/// Dispose UnitOfWork
/// </summary>
public void Dispose()
{
UnitOfWork.Dispose();
}
}
IGrupo
public interface IGrupo
{
IEnumerable<Grupo> FindAll();
}
Project Api
GrupoController
public class GrupoController : ControllerBase
{
private readonly IGrupo IGrupoBLL;
public GrupoController(IGrupo grupo)
{
this.IGrupoBLL = grupo;
}
// GET: api/Grupo
[HttpGet]
[Route("All")]
public IEnumerable<Grupo> Get()
{
return IGrupoBLL.FindAll();
}
Startup
public void ConfigureServices(IServiceCollection services)
{
services.ConfigureCors();
services.ConfigureContext(Configuration);
services.ConfigureRepository();
services.ConfigureAuthentication(Configuration);
services.AddControllers();
services.AddMvc();
}
ConfigureRepository
public static class ServiceExtensions
{
public static void ConfigureCors(this IServiceCollection services) {
services.AddCors(c =>
{
c.AddPolicy("CorsAllowAll", builder => builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
//.AllowCredentials()
);
});
}
public static void ConfigureAuthentication(this IServiceCollection services, IConfiguration Configuration)
{
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "uexternado.edu.co",
ValidAudience = "uexternado.edu.co",
IssuerSigningKey = new SymmetricSecurityKey(
Encoding.UTF8.GetBytes(Configuration["PrivateKey"])),
ClockSkew = TimeSpan.Zero
});
}
public static void ConfigureContext(this IServiceCollection services, IConfiguration Configuration) {
services.AddDbContext<DBContext>(options => options.UseSqlServer(Configuration.GetConnectionString("ContextProyectosInvestigacion")));
}
public static void ConfigureRepository(this IServiceCollection services) {
services.AddSingleton<IUnitOfWork, UnitOfWork>();
services.AddScoped<IGrupo, GrupoBLL>();
//services.AddSingleton(typeof(IRepository<>), typeof(Repository<>));
}
}
appsettings.json
"conectionStrings": {
"ContextProyectosInvestigacion": "Server=XXXXXXX;Initial Catalog=ProyectosInvestigacion;Persist Security Info=True;User ID=XXXXX;Password=XXXXXX;"
},
Upvotes: 1
Views: 2921
Reputation: 239260
The exact issue is that you're using AddDbContext<DbContext>
, when you need to specify your actual context type here, i.e. AddDbContext<ProyectosInvestigacionContext>
. Only the exact type registration will do here.
That said, you should have absolutely none of this code. Just look at the code for your repository/UoW. Literally all you're doing is proxying to the EF context methods of virtually the same names with the same params. This is a far too common mistake and one you should nip in the bud now rather than later. The repository/UoW patterns are for low-level data access abstraction, i.e. things like constructing SQL queries. ORMs like EF already implement these patterns for that exact reason. The context is your UoW and each DbSet
is a repository. Wrapping another repository around that doesn't abstract anything. You still have dependencies on EF, your app must still know you're using EF, and all your business logic is still leaking out, so any change to the underlying provider (EF, for example) still necessitates changes outside the repository abstraction. All you're doing here is adding something else you have to test and maintain with absolutely zero benefit.
When you use an ORM like EF, you are opting to use a third-party DAL, rather than writing your own. Writing your own DAL on top of that entirely defeats the purpose. If you want a true abstraction, look into the CQRS, service layer, or microservices patterns. Otherwise, just access your EF context directly in your controller.
Upvotes: 0
Reputation: 4279
I think you need to change ConfigureContext
public static void ConfigureContext(this IServiceCollection services, IConfiguration Configuration) {
services.AddDbContext<ProyectosInvestigacionContext>(options => options.UseSqlServer(Configuration.GetConnectionString("ContextProyectosInvestigacion")));
}
Upvotes: 2