以前我們的 TaskFlow 是所有功能集中在 Controller 裡,雖然可以運作,但未來會不容易管理
我們要改成
前端 / Swagger UI發送 HTTP 請求
TasksController接收請求、決定回傳什麼 HTTP 結果
TaskService負責任務的新增、查詢、修改、刪除
**List TaskItem **暫時儲存任務資料
假設 TasksController 需要使用 TaskService
一般情況可能會自己建立物件
TaskService service = new TaskService();
但使用 DI 後,我們只需要告訴 ASP.NET Core:
「這個 Controller 需要一個 ITaskService。」
ASP.NET Core 就會根據我們的設定提供對應的 TaskService 物件。
例如:
private readonly ITaskService _taskService;
public TasksController(ITaskService taskService)
{
_taskService = taskService;
}
這叫做建構函式注入(Constructor Injection)。
其中:
在昨天的專案新增 Services 資料夾。
1.對 TaskFlow3.Api 按右鍵。
2.選擇「新增資料夾」。
3.輸入 Services。
4.在 Services 裡新增 ITaskService.cs
5.在ITaskService.cs打底下這段程式碼
using TaskFlow3.Api.Models;
namespace TaskFlow3.Api.Services
{
public interface ITaskService
{
List<TaskItem> GetAll();
TaskItem? GetById(int id);
TaskItem Create(string title);
bool Update(int id, string title, bool isCompleted);
bool Delete(int id);
}
}
在 Services 裡建立第二個檔案:TaskService.cs
using TaskFlow3.Api.Models;
namespace TaskFlow3.Api.Services
{
public class TaskService : ITaskService
{
private readonly List<TaskItem> _tasks = new()
{
new TaskItem
{
Id = 1,
Title = "完成 C# 作業",
IsCompleted = false
},
new TaskItem
{
Id = 2,
Title = "複習英文",
IsCompleted = true
}
};
private int _nextId = 3;
// 取得所有任務
public List<TaskItem> GetAll()
{
return _tasks;
}
// 取得指定任務
public TaskItem? GetById(int id)
{
return _tasks.Find(t => t.Id == id);
}
// 新增任務
public TaskItem Create(string title)
{
TaskItem task = new TaskItem
{
Id = _nextId++,
Title = title,
IsCompleted = false
};
_tasks.Add(task);
return task;
}
// 修改任務
public bool Update(
int id,
string title,
bool isCompleted)
{
TaskItem? task = GetById(id);
if (task == null)
{
return false;
}
task.Title = title;
task.IsCompleted = isCompleted;
return true;
}
// 刪除任務
public bool Delete(int id)
{
TaskItem? task = GetById(id);
if (task == null)
{
return false;
}
_tasks.Remove(task);
return true;
}
}
}
using TaskFlow3.Api.Services;
var builder = WebApplication.CreateBuilder(args);
// OpenAPI
builder.Services.AddOpenApi();
// Controller
builder.Services.AddControllers();
builder.Services.AddSingleton<ITaskService, TaskService>();
var app = builder.Build();
// 開發環境才啟用 OpenAPI 和 Swagger UI
if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
app.UseSwaggerUI(options =>
{
options.SwaggerEndpoint("/openapi/v1.json", "v1");
});
}
app.UseHttpsRedirection();
// 啟用 Controller 路由
app.MapControllers();
// 測試路由
app.MapGet("/test", () => "伺服器正常運作!");
app.Run();
using Microsoft.AspNetCore.Mvc;
using TaskFlow2.Api.DTOs;
using TaskFlow2.Api.Models;
using TaskFlow2.Api.Services;
namespace TaskFlow2.Api.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class TasksController : ControllerBase
{
private readonly ITaskService _taskService;
// 建構函式注入
public TasksController(ITaskService taskService)
{
_taskService = taskService;
}
// GET /api/tasks
[HttpGet]
public ActionResult<List<TaskDto>> GetTasks()
{
var tasks = _taskService.GetAll();
var result = tasks.Select(t => ToDto(t)).ToList();
return Ok(result);
}
// GET /api/tasks/1
[HttpGet("{id:int}")]
public ActionResult<TaskDto> GetTask(int id)
{
TaskItem? task = _taskService.GetById(id);
if (task == null)
{
return NotFound("找不到這筆任務");
}
return Ok(ToDto(task));
}
// POST /api/tasks
[HttpPost]
public ActionResult<TaskDto> CreateTask(
[FromBody] CreateTaskDto input)
{
if (input == null ||
string.IsNullOrWhiteSpace(input.Title))
{
return BadRequest("任務名稱不可空白");
}
TaskItem task = _taskService.Create(input.Title);
return CreatedAtAction(
nameof(GetTask),
new { id = task.Id },
ToDto(task)
);
}
// PUT /api/tasks/1
[HttpPut("{id:int}")]
public IActionResult UpdateTask(
int id,
[FromBody] UpdateTaskDto input)
{
if (input == null ||
string.IsNullOrWhiteSpace(input.Title))
{
return BadRequest("任務名稱不可空白");
}
bool success = _taskService.Update(
id,
input.Title,
input.IsCompleted
);
if (!success)
{
return NotFound("找不到這筆任務");
}
return NoContent();
}
// DELETE /api/tasks/1
[HttpDelete("{id:int}")]
public IActionResult DeleteTask(int id)
{
bool success = _taskService.Delete(id);
if (!success)
{
return NotFound("找不到這筆任務");
}
return NoContent();
}
// Model 轉 DTO
private static TaskDto ToDto(TaskItem task)
{
return new TaskDto
{
Id = task.Id,
Title = task.Title,
IsCompleted = task.IsCompleted
};
}
}
}
結果
