# 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
    }
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://monksoul.gitbook.io/hoa/shujukucaozuoshinan/shujukucangchuduixiang.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
