繁体   English   中英

netcore 中的通用存储库和工作单元

[英]Generic repository and unit of work in netcore

我是 netcore 的菜鸟,我在 netcore 中使用通用存储库和工作单元。 但我遇到了问题,我的项目是 3 层,Api,BLL,DA,我有这个错误。 尝试激活“ProyectosInvestigacion.DAL.Class.UnitOfWork”时无法解析“ProyectosInvestigacion.DAL.ProyectosInvestigacionContext”类型的服务。

感谢你的支持

项目DA

存储库

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

    } ....

工作单位

public interface IUnitOfWork : IDisposable
{
    void SaveChanges();

    IRepository<Grupo> GrupoRepository { get; }
}

工作单位

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

伊格鲁波

public interface IGrupo
{
    IEnumerable<Grupo> FindAll();
}

项目 Api

组控制器

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

配置存储库

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

},

我认为您需要更改ConfigureContext

public static void ConfigureContext(this IServiceCollection services, IConfiguration Configuration) {
    services.AddDbContext<ProyectosInvestigacionContext>(options => options.UseSqlServer(Configuration.GetConnectionString("ContextProyectosInvestigacion")));
}

确切的问题是您正在使用AddDbContext<DbContext> ,当您需要在此处指定您的实际上下文类型时,即AddDbContext<ProyectosInvestigacionContext> 只有确切的类型注册才会在这里进行。

也就是说,您应该绝对没有这些代码。 只需查看您的存储库/UoW 的代码。 从字面上,您所做的只是代理到具有相同参数的几乎相同名称的 EF 上下文方法。 这是一个太常见的错误,你应该现在而不是以后把它扼杀在萌芽状态。 存储库/UoW 模式用于低级数据访问抽象,即构建 SQL 查询之类的事情。 正是因为这个原因,像 EF 这样的 ORM已经实现了这些模式。 上下文是您的 UoW,每个DbSet都是一个存储库。 围绕它包装另一个存储库不会抽象任何东西。 您仍然依赖于 EF,您的应用程序必须仍然知道您正在使用 EF,并且您的所有业务逻辑仍在泄漏,因此对底层提供程序(例如 EF)的任何更改仍然需要在存储库抽象之外进行更改。 你在这里所做的只是添加一些你必须测试和维护的东西,而且收益绝对为零

当您使用像 EF 这样的 ORM 时,您选择使用第三方 DAL,而不是自己编写。 在此基础上编写自己的 DAL 完全违背了目的。 如果您想要真正的抽象,请查看 CQRS、服务层或微服务模式。 否则,只需直接在 controller 中访问您的 EF 上下文。

在这个示例项目中,通用存储库模式被定义为简单且有用。 CRUD 操作和服务集成是不言自明的。 您可以查看我的朋友存储库。

链接在这里

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM