[IT] EntityFramework Commands

前置作業 需安裝以下 Packages Microsoft.EntityFrameworkCore Microsoft.entityFrameworkCore.Design Microsoft.EntityFrameworkCore.Tools 設置好 []DbContext 範例 public class AppDbContext : DbContext { public DbSet<Reminder> Reminders { get; set; } = null!; public DbSet<User> Users { get; set; } = null!; public AppDbContext() { } protected override void OnConfiguring(DbContextOptionsBuilder options) { options.UseNpgsql("Host=localhost;Port=5432;Username=********;Password=********;Database=testdb"); } } 若是實作的 DbContext 沒有合適的建構子,是無法進行 migration 的。 如果 DbContext 採用依賴注入的方式,且程式的 entry 又不在同一個專案底下,則需要覆寫 OnConfiguring() 來提供 Database 的連線資訊。 建構好對應的 Entity,需包含至少一個帶有 Id 的 property。 由於我們要進行持久化(persistance)的物件通常是聚合根(aggregate root),可透過繼承以下的抽象物件 Entity來統一 Id property。 又聚合根通常又會作為 DomainEvent 的發起者,透過 EventBus 來進行推播。可參考 EventBus Middleware 的實作。 migration 指令 進行 Migration 初始化 以下指令會產生將 DbContext 遷移至 Database 的 migration codes。 -p 或是 -project 用以指定專案。 dotnet ef migrations add InitialMigration -p src/CleanWebApi....

<span title='2024-03-31 14:37:44 +0800 +0800'>March 31, 2024</span>&nbsp;·&nbsp;2 min&nbsp;·&nbsp;Rain Hu

[IT] 用 C# 建置 Clean Architecture 專案

Configure C# Solution step by step 開啟 Terminal 新增解決方案 dontet new sln -o MySln 移至方案目錄 cd MySln 根據解決方案 hierarchy 建構專案 dotnet new webapi -o MySln.Api dotnet new classlib -o MySln.Application dotnet new classlib -o MySln.Domain dotnet new classlib -o MySln.Infrastructure dotnet new classlib -o MySln.Contracts 將所有專案加進解決方案 for proj in $(ls -r **/*.csproj) dotnet sln add $proj 建立專案之間的 dependency dotnet add MySln.Api reference MySln.Application MySln.Infrastructure MySln.Contracts dotnet add MySln.Infrastructure reference MySln.Application dotnet add MySln....

<span title='2024-03-09 13:59:22 +0800 +0800'>March 9, 2024</span>&nbsp;·&nbsp;1 min&nbsp;·&nbsp;Rain Hu

[IT] 使用 Clean Architecture + DDD 建置 Restful API

程式碼 https://github.com/intervalrain/webapi_ca/ 正文 建置 Solution 首先先參考 Clean Architecture 最經典的同心圓,來確定我們需要將我們的解決方案做哪些分層: 我將使用 Restful API 做為我們 I/O (Presentation Layer) 並且我需要配備身份驗證的機制 (Presentation Layer) 我使用 PostgresDB 作為我的 (Infrastructure Layer) 我的核心商業邏輯 (Application / Domain Layer) 創建專案 dotnet new sln -o Mysln 進入專案所在的資料夾 cd Mysln 根據預先的分層建立專案資料夾,並且使用 dotnet 指令建立相對應的專案類型。 Api –> WebAPI Infrastructure –> classlib Contracts –> classlib Application –> classlib Domain –> classlib dotnet new webapi -o Mysln.Api dotnet new classlib -o Mysln.Contracts dotnet new classlib -o Mysln....

<span title='2024-02-26 15:03:15 +0800 +0800'>February 26, 2024</span>&nbsp;·&nbsp;6 min&nbsp;·&nbsp;Rain Hu

[IT] .NET Maui

.NET Maui .NET Maui 是一個跨平台的桌面與手機應用開發框架,它支援 iOS、Android、macOS、Windows。 不同於 Xamarin,.NET Maui 只需要一個專案便可以導向不同的平台。 架構 一個 .NET Maui 專案底下,預設會有幾個資料夾與檔案,其關係如下圖: /Platforms 底下的各個資料夾為不同平台的入口,不同的平台各有一個 Program.cs。 各個 Program.cs 內又會透過注入該 namespace 底下的 AppDelegate ,將入口指向 MauiProgram 的 CreateMauiApp(),就此將不同平台路由到 MauiProgram.cs 這個統一的入口。 public class Program { static void Main(string[] args) { UIApplication.Main(args, null, typeof(AppDelegate)); } } [Register("AppDelegate")] public class AppDelegate : MauiUIApplicationDelegate { protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp(); } 關係如下圖: graph TD; iOS-->MauiProgram.cs; Android-->MauiProgram.cs; Windows-->MauiProgram.cs; macOS-->MauiProgram.cs; MauiProgram.cs-->App; App-->AppShell; AppShell-.->Page1; AppShell-.->Page2; AppShell-.->Page3; AppShell-....

<span title='2024-01-28 13:30:34 +0800 +0800'>January 28, 2024</span>&nbsp;·&nbsp;2 min&nbsp;·&nbsp;Rain Hu

[IT] CORS 跨原始來源要求

TL;DR CORS (Cross-Origin Resource Sharing) 是一個支援安全跨源請求和資料傳輸的機制,用於在瀏覽器和伺服器之間進行跨源請求。 這是一個 W3C 標準,可讓伺服器放寬相同原始來源原則。 不是安全性功能,CORS 會放寬安全性。 允許 CORS 並不會增強 API 的安全性。CORS 的運作方式 允許伺服器明確允許某些跨原始來源要求,同時拒絕其他要求。 比舊版技術 (例如:JSONP) 更安全且更有彈性。 何謂相同原始來源 如果兩個 URL 具有相同的配置、主機和連接埠,則其原始來源相同 (RFC 6454)。 這兩個 URL 具有相同的原始來源: https://example.com/foo.html https://example.com/bar.html 這些 URL 的原始來源與前兩個 URL 不同: https://example.net:不同的網域 https://www.example.com/foo.html:不同的子網域 http://example.com/foo.html:不同的配置 https://example.com:9000/foo.html:不同的連接埠 如何啟動 CORS 有三種方式可以啟用 CORS: 在中介軟體中,使用具名原則或預設原則。 使用端點路由。 使用 [EnableCors] 屬性。 搭配具名原則使用 [EnableCors] 屬性能夠以最精細的程度來控制對於支援 CORS 之端點的限制。 必須以正確的順序呼叫 UseCors。例如,在使用 UseResponseCaching 時,必須先呼叫 UseCors,再呼叫 UseResponseCaching。 具有具名原則和中介軟體的 CORS var MyAllowSpecificOrigins = "_myAllowSpecificOrigins"; var builder = WebApplication....

<span title='2024-01-19 00:41:51 +0800 +0800'>January 19, 2024</span>&nbsp;·&nbsp;3 min&nbsp;·&nbsp;Rain Hu