> For the complete documentation index, see [llms.txt](https://monksoul.gitbook.io/hoa/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://monksoul.gitbook.io/hoa/shujukucaozuoshinan/shujukucangchuduixiang.md).

# 9.3、关于仓储（IRepository）

## 仓储定义

在领域层和数据映射层的中介,使用类似集合的接口来存取领域对象，实际上，仓储被用于领域对象在数据库上的操作（实体Entity和值对象Value types）。一般来说,我们针对不同的实体(或聚合根Aggregate Root)会创建相对应的仓储。

简单来说，仓储就是数据存取操作的载体，但不限定于数据库。

## IRepository\<TEntity> 和 EFCoreRepository\<TEntity>

Hoa Framework 框架内置了 `IRepository<TEntity>` 操作接口 和 实现该接口的 EF Core 实现类 `EFCoreRepository<TEntity>` 。

在 `Hoa.Core` 项目层，`EFCoreRepository<TEntity>` 作为 `IRepository<TEntity>` 默认注册实例类型，也就是通过依赖注入 `IRepository<TEntity>` ，容器会自动创建 `EFCoreRepository<TEntity>` 的实例。

`IRepository<TEntity>` 封装了应用开发中常用的数据操作方法，也支持自定义拓展。

## IDynamicRepository\<TEntity, TDbContextIdentifier> 和 EFCoreDynamicRepository\<TEntity, TDbContextIdentifier>

在 Hoa Framework v1.2.0 版本中，新增了 **IDynamicRepository\<TEntity,TDbContextIdentifier>** 和 `EFCoreDynamicRepository<TEntity,TDbContextIdentifier>` 接口对象，支持多数据库上下文操作。

需要读写分离、多数据库上下文操作可查看 [9.11、多上下文、读写分离](https://monksoul.gitbook.io/hoa/shujukucaozuoshinan/duoshangxiawen_duxiefenli) 文档。

## 仓储使用

仓储实际上也是[服务](https://monksoul.gitbook.io/hoa/kongzhiqihefuwu)，是针对数据存取操作抽象出来的[服务](https://monksoul.gitbook.io/hoa/kongzhiqihefuwu)，所以，仓储的使用和[服务](https://monksoul.gitbook.io/hoa/kongzhiqihefuwu)使用大致相同，采用构造函数注入方式创建对象。

**唯一和服务不一样的是，仓储通常对应着数据库表的操作，所以需要配置数据表信息。**&#x6211;们只需要在 `Hoa.EntityFramework.Core.HoaDbContext` 中申明表 `DbSet<TEntity>` 属性即可。

### 第一步：配置 DbSet\<TEntity>

例如：

```csharp
using Microsoft.EntityFrameworkCore;

namespace Hoa.EntityFrameworkCore
{
    public partial class HoaDbContext : DbContext
    {
        public HoaDbContext(DbContextOptions<HoaDbContext> options)
            : base(options)
        {
        }
        
        // 配置 DbSet<TEntity>
        public virtual DbSet<TEntity> TEntities{ get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            if (!optionsBuilder.IsConfigured)
            {
                optionsBuilder.UseSqlServer("Name=HoaDatabase");
            }
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            OnModelCreatingPartial(modelBuilder);
        }

        partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
    }
}
```

### 第二步：构造函数注入使用

```csharp
using Hoa.Core.Test.Entities;
using Hoa.Dependencies;
using Hoa.ServiceController.Attributes;
using Hoa.UnitOfWork.Repositories;
using System.ComponentModel.DataAnnotations;

namespace Hoa.Application.Test
{
    [HoaServiceController]
    public class TestAppService : ITestAppService, IAppServiceDependency
    {
        // 申明要操作的数据表仓储
        private readonly IRepository<TestEntity> _testRepository;
        // 在构造函数中注入
        public TestAppService(
            IRepository<TestEntity> testRepository)
        {
            _testRepository = testRepository;
        }

        // ... Other Codes
    }
}
```
