# Repository 層架構說明

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

## 架構結構

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

## 核心介面

### IRepository<T> - 通用 Repository 介面
提供基礎 CRUD 操作：
- `GetByIdAsync(int id)` - 根據 ID 獲取實體
- `GetAllAsync()` - 獲取所有實體
- `AddAsync(T entity)` - 新增實體
- `UpdateAsync(T entity)` - 更新實體
- `DeleteAsync(int id)` - 刪除實體

### BaseRepository<T> - Repository 基礎實作
實作通用 Repository 介面，提供：
- Entity Framework Core 集成
- 統一錯誤處理
- 異步操作支持
- 基礎查詢優化

## 具體 Repository

### IUserRepository / UserRepository
專門處理用戶相關數據操作：
- 繼承自 `IRepository<User>`
- 提供用戶特定的查詢方法
- 處理用戶認證相關邏輯

## 使用方式

### 依賴注入配置
在 `ServiceCollectionExtensions.cs` 中註冊：
```csharp
services.AddScoped(typeof(IRepository<>), typeof(BaseRepository<>));
services.AddScoped<IUserRepository, UserRepository>();
```

### 在 Service 中使用
```csharp
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. 更新本文檔

### 實作範例
```csharp
// 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 開發團隊