Generi c хранилище и единица работы в netcore - PullRequest
1 голос
/ 08 апреля 2020

Я noob в netcore, я использую общий c репозиторий и единицу работы в netcore. но у меня проблемы, мой проект состоит из 3 слоев, Api, BLL, DA, у меня есть эта ошибка. Не удалось разрешить службу для типа «ProyectosInvestigacion.DAL.ProyectosInvestigacionContext» при попытке активировать «ProyectosInvestigacion.DAL.Class.UnitOfWork».

Благодарим Вас за поддержку

Project DA

IR-репозиторий

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);

}

Репозиторий

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; }  ....

Проект 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();
    }

Запуск

 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;"

},

Ответы [ 2 ]

2 голосов
/ 08 апреля 2020

Я думаю, вам нужно изменить ConfigureContext

public static void ConfigureContext(this IServiceCollection services, IConfiguration Configuration) {
    services.AddDbContext<ProyectosInvestigacionContext>(options => options.UseSqlServer(Configuration.GetConnectionString("ContextProyectosInvestigacion")));
}
0 голосов
/ 08 апреля 2020

Точная проблема заключается в том, что вы используете AddDbContext<DbContext>, когда вам нужно указать свой фактический тип контекста здесь, то есть AddDbContext<ProyectosInvestigacionContext>. Здесь будет использоваться только точная регистрация типов.

Тем не менее, у вас не должно быть абсолютно никакого этого кода. Просто посмотрите на код вашего репозитория / UoW. Буквально все , которое вы делаете, - это использование методов контекста EF с практически одинаковыми именами с одинаковыми параметрами. Это слишком распространенная ошибка, и ее следует пресечь сейчас, а не позже. Шаблоны хранилища / UoW предназначены для низкоуровневой абстракции доступа к данным, то есть для создания запросов типа SQL. ORM, такие как EF , уже реализуют эти шаблоны именно по этой причине. Контекст - это ваш UoW, и каждый DbSet является хранилищем. Обертывание вокруг другого хранилища, которое ничего не абстрагирует. У вас все еще есть зависимости от EF, ваше приложение должно по-прежнему знать, что вы используете EF, и все ваши бизнес-логики c все еще просачиваются, поэтому любое изменение в базовом поставщике (например, EF) все еще требует изменений вне хранилища. абстракция. Все, что вы здесь делаете, это добавляете что-то еще, что вам нужно протестировать и поддерживать с абсолютно нулевым преимуществом.

Когда вы используете ORM, такой как EF, вы выбираете стороннее DAL, а не писать свой собственный. Написание собственного DAL поверх всего этого полностью противоречит цели. Если вам нужна настоящая абстракция, посмотрите на шаблоны CQRS, сервисного уровня или микросервисов. В противном случае просто получите доступ к своему контексту EF прямо в контроллере.

...