簡體   English   中英

CRUD的通用類 - 使用存儲庫和工作單元模式的C#中的依賴注入

[英]Generic Class for CRUD - Dependency Injection in C# using Repository and Unit Of Work Pattern

嘗試使用依賴注入,工作單元和存儲庫模式創建用於在C#中實現基本CRUD操作的通用存儲庫類。

我對這些概念很陌生。 以下是我的代碼。

    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等方法的訪問將丟失。 如何在不丟失這些方法的情況下刪除上述依賴項。 我想通過構造函數從我的子類庫中傳遞實際的上下文。

我想,這應該做,你想要什么。 如果將缺少的方法添加到接口,則基類(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並將其交給Type,您想在那里訪問它。 我只想將它與GenericRepository一起使用,那么你可能不需要接口和類上的泛型。 因為那樣你只需使用已經通用的Set <U>()。

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

如果不使用“默認數據集”並僅將其與存儲庫一起使用,則可以省略接口上的泛型和上下文。

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 <T>()。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM