Общий класс для CRUD - внедрение зависимостей в C # с использованием репозитория и шаблона единицы работы - PullRequest
0 голосов
/ 26 марта 2019

Попытка создать общий класс репозитория для реализации базовых операций CRUD в C # с использованием внедрения зависимостей, единиц работы и шаблонов репозитория.

Я очень новичок в этих понятиях.Ниже приведен мой код.

    public interface IUnitOfWork
    {
        IApplicationUserRepository Users { get; }

        ICompanyRepository Companies { get; }

        void Complete();
    }

  public class UnitOfWork : IUnitOfWork
    {
        private readonly ApplicationDbContext _context;
        public IApplicationUserRepository Users { get; private set; }
        public ICompanyRepository Companies { get; private set; }

        public UnitOfWork(ApplicationDbContext context)
        {
            _context = context;
            Users = new ApplicationUserRepository(context);
            Companies = new CompanyRepository(context);
        }

        public void Complete()
        {
            _context.SaveChanges();
        }
    }

 public interface IApplicationDbContext
    {
        DbSet<Company> Companies { get; set; }
        IDbSet<ApplicationUser> Users { get; set; }
        IDbSet<IdentityRole> Roles { get; set; }
    }

 public class ApplicationDbContext : IdentityDbContext<ApplicationUser>, IApplicationDbContext
    {
        public DbSet<Company> Companies { get; set; }
        public ApplicationDbContext()
            : base("DefaultConnection", throwIfV1Schema: false)
        {
        }

        public static ApplicationDbContext Create()
        {
            return new ApplicationDbContext();
        }
    }

public abstract class GenericRepository<T> : IGenericRepository<T>
        where T : class, new()
    {
        protected GenericRepository(ApplicationDbContext context)
        {
            _dbContext = context;
        }
        private ApplicationDbContext _dbContext;


        private static IEnumerable<T> entity;

        public IEnumerable<T> Get(bool forceRefresh = false)
        {
            if (forceRefresh || entity == null)
                entity = _dbContext.Set<T>();

            return entity;
        }

        public async Task AddAsync(T entity)
        {
            _dbContext.Set<T>().Add(entity);
            await _dbContext.SaveChangesAsync();
        }

        public async Task RemoveAsync(T entity)
        {
            _dbContext.Set<T>().Remove(entity);
            await _dbContext.SaveChangesAsync();
        }
    }

В приведенном выше коде я хотел бы передать IApplicationDBContext вместо ApplicationDBContext для удаления жесткой связи, но когда я использую IApplicationDbContext, доступ к таким методам, как Set и SaveChanges, теряется.Как мне удалить вышеуказанную зависимость без потери этих методов.Я хотел бы передать фактический контекст из моих дочерних классов репозиториев через конструктор.

1 Ответ

0 голосов
/ 05 апреля 2019

Я думаю, это должно делать то, что вы хотите. Если вы добавляете недостающие методы в интерфейс, базовый класс (DbContext) уже реализовал его. Так что нет необходимости внедрять его снова.

public interface IApplicationDbContext<T> where T: class
{
    //Identity Management
    IDbSet<ApplicationUser> Users { get; set; }
    IDbSet<IdentityRole> Roles { get; set; }

    //Datamanagement
    DbSet<T> DataSet { get; set; } //the Dataset of T

    DbSet<U> Set<U>() where T: class; //get other DataSets
    int SaveChanges(); //save the changes
}

Затем сделайте ApplicationDbContext Generic и передайте ему тип, к которому вы хотите получить доступ. Я хочу, чтобы вы использовали его только с GenericRepository, тогда вам может не понадобиться Generics для интерфейса и класса. Потому что тогда вы просто используете уже общий набор ().

public class ApplicationDbContext<T> : IdentityDbContext<ApplicationUser>, IApplicationDbContext<T>
{
    public DbSet<T> DataSet{ get; set; }
    public ApplicationDbContext()
        : base("DefaultConnection", throwIfV1Schema: false)
    {
    }

    public static ApplicationDbContext Create<T>()
    {
        return new ApplicationDbContext<T>();
    }
}

Теперь, когда контекст является общим и интерфейс имеет методы, вы можете использовать Интерфейс в Репозитории.

public abstract class GenericRepository<T> : IGenericRepository<T> where T : class, new()
{
    protected GenericRepository(IApplicationDbContext<T> context)
    {
        _dbContext = context;
    }
    private TApplicationDbContext<T> _dbContext;


    private static IEnumerable<T> entity;

    public IEnumerable<T> Get(bool forceRefresh = false)
    {
        if (forceRefresh || entity == null)
            entity = _dbContext.Set<T>();

        return entity;
    }

    public async Task AddAsync(T entity)
    {
        _dbContext.Set<T>().Add(entity);
        await _dbContext.SaveChangesAsync();
    }

    public async Task RemoveAsync(T entity)
    {
        _dbContext.Set<T>().Remove(entity);
        await _dbContext.SaveChangesAsync();
    }
}

Если вы не используете «набор данных по умолчанию» и используете его только с репозиторием, вы можете опустить Generics в интерфейсе и контексте.

public interface IApplicationDbContext
{
    //Identity Management
    IDbSet<ApplicationUser> Users { get; set; }
    IDbSet<IdentityRole> Roles { get; set; }

    DbSet<U> Set<U>() where T: class; //get DataSets
    int SaveChanges(); //save the changes
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>, IApplicationDbContext
{
    public ApplicationDbContext()
        : base("DefaultConnection", throwIfV1Schema: false)
    {
    }

    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }
}

public abstract class GenericRepository<T> : IGenericRepository<T> where T : class, new()
{

    protected GenericRepository(IApplicationDbContext context)
    {
        _dbContext = context;
    }
    private IApplicationDbContext _dbContext;


    private static IEnumerable<T> entity;

    public IEnumerable<T> Get(bool forceRefresh = false)
    {
        if (forceRefresh || entity == null)
            entity = _dbContext.Set<T>();

        return entity;
    }

    public async Task AddAsync(T entity)
    {
        _dbContext.Set<T>().Add(entity);
        await _dbContext.SaveChangesAsync();
    }

    public async Task RemoveAsync(T entity)
    {
        _dbContext.Set<T>().Remove(entity);
        await _dbContext.SaveChangesAsync();
    }
}

И, конечно, если вам действительно нравятся универсальный интерфейс и контекст, вы можете использовать свойство DataSet в репозитории вместо .Set ().

...