【问题标题】:Getting generic repository with generic dbContext (multiple dbContext)使用通用 dbContext(多个 dbContext)获取通用存储库
【发布时间】:2018-09-06 07:57:34
【问题描述】:

在我的 asp.net core 2 api 项目中使用具有多个上下文的实体框架构建通用存储库时,我迷路了。

我需要的是在不知道控制器使用哪个上下文的情况下将我的存储库注入控制器。

数据库上下文

public interface IDbContext
{
}

public interface IBlogContext : IDbContext
{
}

public interface IBlogLogContext : IDbContext
{
}

存储库

public class EfRepository<TEntity> : IRepository<TEntity> where TEntity : class, IEntity
{
    private readonly IDbContext _context;
    private readonly DbSet<TEntity> _dbSet;

    public EfRepository(IDbContext context)
    {
        _context = context;
        _dbSet = _context.Set<TEntity>();
    }
    /* other stuff */
}     

启动

public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<BlogContext>(options =>
        {

options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))
            .UseLoggerFactory(_logger);
        });
        services.AddDbContext<BlogLogContext>(options =>
        {
            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
        });
        services.AddScoped(typeof(IRepository<>), typeof(EfRepository<>));

        services.AddScoped<IBlogContext, BlogContext>();
        services.AddScoped<IBlogLogContext, BlogLogContext>();

        services.AddUnitOfWork<BlogContext, BlogLogContext>();

    }

控制器

public class UserController : Controller
{
    private readonly IRepository<User> _repository;
    private readonly IAuthorService _authorService;
    private readonly ILogger<UserController> _logger;

    public UserController(IRepository<User> repository, IAuthorService authorService, ILogger<UserController> logger)
    {
        _repository = repository;
        _authorService = authorService;
        _logger = logger;
    }
}

当我在控制器构造函数中注入IRepository&lt;User&gt; 时,.net core DI 如何解析UserBlogContext 的实体,所以IDbContext 在我的EfRepository 实现中应该是BlogContext

【问题讨论】:

  • 我好像听到 Walter Sobchak “你正在进入一个痛苦的世界
  • 个人意见:存储库模式不会给你带来太多的 EF,除了更多的工作。

标签: entity-framework repository asp.net-core-2.0 repository-pattern


【解决方案1】:

我用这样的 DbContext 通用参数定义了我的 EfRepository:

 public class EfRepository<TDbContext, TEntity> : IRepository<TEntity>
    where TDbContext : DbContext
    where TEntity : class, IEntity
{
    public EfRepository(IDbContextProvider<TDbContext> dbContextProvider)
    {
    }
}

并获得如下 DbContext-Entity 信息:

//EntityTypeInfo is a class has EntityType & DeclaringType props
private IList<EntityTypeInfo> GetEntityTypeInfos()
{
    var result = new List<EntityTypeInfo>();
    var dbContextTypes = this.GetType().Assembly.GetTypes().Where(t => (typeof(DbContext).IsAssignableFrom(t)));
    foreach (var dbContextType in dbContextTypes)
    {
        result.AddRange(
            from property in dbContextType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
            where
                Common.IsAssignableToGenericType(property.PropertyType, typeof(DbSet<>)) &&
                Common.IsAssignableToGenericType(property.PropertyType.GenericTypeArguments[0], typeof(IEntity))
            select new EntityTypeInfo(
                property.PropertyType.GenericTypeArguments[0],
                property.DeclaringType
                );
    }
    return result;
}

所以我可以用 EntityTypeInfo 列表添加相关服务:

var entityTypeInfos = GetEntityTypeInfos();
foreach (var entityTypeInfo in entityTypeInfos)
{
    //
    //Add IDbContextProvider and DbContext services Here
    //

    //Add IRepository services like this
    var repositoryInterface =typeof(IRepository<>);
    var repositoryImplementation =typeof(EfRepository<,>);

    var genericRepositoryType = repositoryInterface.MakeGenericType(entityTypeInfo.EntityType);
    if (!Common.IocHasRegister(genericRepositoryType))
    {
        var implRepositoryType = repositoryImplementation.MakeGenericType(entityTypeInfo.DeclaringType, entityTypeInfo.EntityType);

        services.AddScoped(genericRepositoryType, implRepositoryType);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多