dramaling-vocab-learning/backend/DramaLing.Api/Repositories/README.md

3.0 KiB
Raw Blame History

Repository 層架構說明

概述

Repository 層負責數據訪問邏輯,提供統一的數據操作介面,遵循 Repository Pattern 和 Unit of Work 模式。

架構結構

Repositories/
├── README.md                 # 本文檔
├── IRepository.cs           # 通用 Repository 介面
├── BaseRepository.cs        # Repository 基礎實作
├── IUserRepository.cs       # 用戶 Repository 介面
└── UserRepository.cs        # 用戶 Repository 實作

核心介面

IRepository - 通用 Repository 介面

提供基礎 CRUD 操作:

  • GetByIdAsync(int id) - 根據 ID 獲取實體
  • GetAllAsync() - 獲取所有實體
  • AddAsync(T entity) - 新增實體
  • UpdateAsync(T entity) - 更新實體
  • DeleteAsync(int id) - 刪除實體

BaseRepository - Repository 基礎實作

實作通用 Repository 介面,提供:

  • Entity Framework Core 集成
  • 統一錯誤處理
  • 異步操作支持
  • 基礎查詢優化

具體 Repository

IUserRepository / UserRepository

專門處理用戶相關數據操作:

  • 繼承自 IRepository<User>
  • 提供用戶特定的查詢方法
  • 處理用戶認證相關邏輯

使用方式

依賴注入配置

ServiceCollectionExtensions.cs 中註冊:

services.AddScoped(typeof(IRepository<>), typeof(BaseRepository<>));
services.AddScoped<IUserRepository, UserRepository>();

在 Service 中使用

public class SomeService
{
    private readonly IUserRepository _userRepository;

    public SomeService(IUserRepository userRepository)
    {
        _userRepository = userRepository;
    }

    public async Task<User> GetUserAsync(int id)
    {
        return await _userRepository.GetByIdAsync(id);
    }
}

設計原則

  1. 單一職責:每個 Repository 只負責一個 Entity 的數據訪問
  2. 介面隔離:提供清晰的介面定義,方便測試和替換實作
  3. 依賴反轉Service 層依賴於 Repository 介面,而非具體實作
  4. 異步優先:所有數據操作都使用異步方法

擴展指南

新增 Repository

  1. 建立介面檔案:I{Entity}Repository.cs
  2. 建立實作檔案:{Entity}Repository.cs
  3. 在 ServiceCollectionExtensions 中註冊
  4. 更新本文檔

實作範例

// IFlashcardRepository.cs
public interface IFlashcardRepository : IRepository<Flashcard>
{
    Task<IEnumerable<Flashcard>> GetByUserIdAsync(int userId);
}

// FlashcardRepository.cs
public class FlashcardRepository : BaseRepository<Flashcard>, IFlashcardRepository
{
    public FlashcardRepository(DramaLingDbContext context) : base(context) { }

    public async Task<IEnumerable<Flashcard>> GetByUserIdAsync(int userId)
    {
        return await _context.Flashcards
            .Where(f => f.UserId == userId)
            .ToListAsync();
    }
}

版本: 1.0 最後更新: 2025-09-30 維護者: DramaLing 開發團隊