GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com โ€” GitHub - dotnetdev-kr/dotnet-fba-examples: .NET File-based App Example Codes

BranchesTags
Open more actions menu

Latest commit

 

History

13 Commits
13 Commits

Folders and files

NameName
Last commit message
Last commit date
07-blazor-wasm
07-blazor-wasm
 
 
.gitignore
.gitignore
 
 
01-shell-alt.cs
01-shell-alt.cs
 
 
01-shell-standard.cs
01-shell-standard.cs
 
 
01-shell-standard.fsx
01-shell-standard.fsx
 
 
02-random-webapi.cs
02-random-webapi.cs
 
 
02-random-webapi.fsx
02-random-webapi.fsx
 
 
03-apphost.cs
03-apphost.cs
 
 
03-apphost.json
03-apphost.json
 
 
03-minapi.cs
03-minapi.cs
 
 
03-minapi.fsx
03-minapi.fsx
 
 
03-worker.cs
03-worker.cs
 
 
03-worker.fsx
03-worker.fsx
 
 
04-avalonia.cs
04-avalonia.cs
 
 
04-avalonia.fsx
04-avalonia.fsx
 
 
05-native-aot.cs
05-native-aot.cs
 
 
05-native-aot.java
05-native-aot.java
 
 
05-native-aot.js
05-native-aot.js
 
 
05-native-aot.py
05-native-aot.py
 
 
05-staticlib-aot.cs
05-staticlib-aot.cs
 
 
05-staticlib-c.c
05-staticlib-c.c
 
 
06-agui-client.cs
06-agui-client.cs
 
 
06-agui-server.cs
06-agui-server.cs
 
 
LICENSE
LICENSE
 
 
README.md
README.md
 
 

Repository files navigation

.Net File-Based Application (FBA) Zero to Hero

๐Ÿš€ .NET์˜ ๊ฐ•๋ ฅํ•œ FBA(File-Based Application) ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•œ ์‹ค์ „ ์˜ˆ์ œ ๋ชจ์Œ

.Net File-Based Application (FBA) ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•œ ๋‹ค์–‘ํ•œ ์˜ˆ์ œ ์ฝ”๋“œ ๋ชจ์Œ์ž…๋‹ˆ๋‹ค. .NET 10 ์ด์ƒ์˜ FBA ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‹จ์ผ ํŒŒ์ผ๋กœ ์ž‘์„ฑ๋œ ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ C# ์Šคํฌ๋ฆฝํŠธ ์˜ˆ์ œ๋“ค์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

๋ฐœํ‘œ ์ž๋ฃŒ ๊ฐ™์ด๋ณด๊ธฐ: https://1drv.ms/p/c/318484c5aad6b73d/EQNehpg4jN5CmVcTh-qDoecBGqBe3gMwuGh3bbHf7EW4yQ?e=M1RstJ

๐ŸŽฏ FBA๋ž€ ๋ฌด์—‡์ธ๊ฐ€์š”?

File-Based Application(FBA)์€ .NET์˜ ํ˜์‹ ์ ์ธ ๊ธฐ๋Šฅ์œผ๋กœ, ๋‹จ์ผ C# ํŒŒ์ผ์„ ํ”„๋กœ์ ํŠธ ํŒŒ์ผ(.csproj) ์—†์ด ์ง์ ‘ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. ์ด๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์žฅ์ ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค:

  • โœจ ๊ฐ„ํŽธํ•œ ์‹œ์ž‘: ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ ์—†์ด ๋‹จ์ผ ํŒŒ์ผ๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ž‘์„ฑ
  • ๐Ÿ”ง ๋น ๋ฅธ ํ”„๋กœํ† ํƒ€์ดํ•‘: ์•„์ด๋””์–ด๋ฅผ ๋น ๋ฅด๊ฒŒ ํ…Œ์ŠคํŠธํ•˜๊ณ  ๊ฒ€์ฆ
  • ๐Ÿ“ฆ ์˜์กด์„ฑ ๊ด€๋ฆฌ: #:package ๋””๋ ‰ํ‹ฐ๋ธŒ๋กœ NuGet ํŒจํ‚ค์ง€ ์ง์ ‘ ์ฐธ์กฐ
  • ๐ŸŽญ SDK ์„ ํƒ: #:sdk ๋””๋ ‰ํ‹ฐ๋ธŒ๋กœ ํ•„์š”ํ•œ SDK ์ง€์ •
  • โš™๏ธ ๋นŒ๋“œ ์†์„ฑ: #:property ๋””๋ ‰ํ‹ฐ๋ธŒ๋กœ MSBuild ์†์„ฑ ์„ค์ •
  • ๐Ÿš ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰: Shebang(#!/usr/bin/env dotnet)์„ ํ†ตํ•œ ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰

๐Ÿ“‹ ๋ชฉ์ฐจ

  • C# File-Based Application (FBA) Zero to Hero
    • ๐ŸŽฏ FBA๋ž€ ๋ฌด์—‡์ธ๊ฐ€์š”?
    • ๐Ÿ“‹ ๋ชฉ์ฐจ
    • ๐Ÿ’ป ์š”๊ตฌ์‚ฌํ•ญ
      • ํ•„์ˆ˜ ์š”๊ตฌ์‚ฌํ•ญ
      • ์„ ํƒ์  ์š”๊ตฌ์‚ฌํ•ญ
      • ๊ฐœ๋ฐœ ๋„๊ตฌ (๊ถŒ์žฅ)
    • ๐Ÿš€ ๋น ๋ฅธ ์‹œ์ž‘
    • ๐Ÿ“š C# ์˜ˆ์ œ ์„ค๋ช…
      • 01. Shell Scripts
        • 01-shell-standard.cs
        • 01-shell-alt.cs
      • 02. Web API
        • 02-random-webapi.cs
      • 03. Aspire App Host
        • ๊ตฌ์„ฑ ์š”์†Œ
      • 04. Avalonia GUI
        • 04-avalonia.cs
      • 05. Native AOT
        • ์˜ˆ์ œ ํŒŒ์ผ
        • ๋™์  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ (.dylib) ์˜ˆ์ œ
        • ์ •์  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ (.a) ์˜ˆ์ œ
      • 06. AG-UI (AI Agents)
      • 07. Blazor WebAssembly
        • ๊ตฌ์„ฑ ์š”์†Œ
        • ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ
    • ๐Ÿ“š F# ์˜ˆ์ œ ์„ค๋ช…
      • 01. Shell Scripts (F#)
        • 01-shell-standard.fsx
      • 02. Web API (F#)
        • 02-random-webapi.fsx
      • 03. Aspire App Host (F#)
        • ๊ตฌ์„ฑ ์š”์†Œ
      • 04. Avalonia GUI (F#)
        • 04-avalonia.fsx
    • ๐Ÿ“– FBA ๋””๋ ‰ํ‹ฐ๋ธŒ ๊ฐ€์ด๋“œ
      • SDK ์ง€์ •
      • ํŒจํ‚ค์ง€ ์ฐธ์กฐ
      • ๋นŒ๋“œ ์†์„ฑ
      • Shebang ์Šคํƒ€์ผ
    • ๐Ÿ”ง ๋ฌธ์ œ ํ•ด๊ฒฐ
      • ์‹คํ–‰ ๊ถŒํ•œ ์˜ค๋ฅ˜
      • ํŒจํ‚ค์ง€ ๋ณต์› ์˜ค๋ฅ˜
      • Native AOT ๋นŒ๋“œ ์‹คํŒจ
      • Aspire Dashboard ์ ‘๊ทผ ๋ถˆ๊ฐ€
      • OpenRouter API ํ‚ค ์˜ค๋ฅ˜
    • ๐Ÿค ๊ธฐ์—ฌํ•˜๊ธฐ
    • ๐Ÿ“„ ๋ผ์ด์„ ์Šค
    • ๐Ÿ”— ์ฐธ๊ณ  ์ž๋ฃŒ
      • ๊ณต์‹ ๋ฌธ์„œ
      • ํ”„๋ ˆ์ž„์›Œํฌ ๋ฐ ๋„๊ตฌ
      • ์ปค๋ฎค๋‹ˆํ‹ฐ
      • ๊ด€๋ จ ํ”„๋กœ์ ํŠธ

๐Ÿ’ป ์š”๊ตฌ์‚ฌํ•ญ

ํ•„์ˆ˜ ์š”๊ตฌ์‚ฌํ•ญ

  • .NET 10.0 SDK ์ด์ƒ
    • FBA ๊ธฐ๋Šฅ์„ ์™„์ „ํžˆ ์ง€์›ํ•˜๋Š” ์ตœ์‹  ๋ฒ„์ „ ์‚ฌ์šฉ ๊ถŒ์žฅ
    • ์„ค์น˜ ํ™•์ธ: dotnet --version
  • ์šด์˜์ฒด์ œ: macOS, Linux, ๋˜๋Š” Windows
    • ๋ชจ๋“  ์˜ˆ์ œ๋Š” ํฌ๋กœ์Šค ํ”Œ๋žซํผ์œผ๋กœ ์„ค๊ณ„๋จ

์„ ํƒ์  ์š”๊ตฌ์‚ฌํ•ญ

  • Python 3.x (05-native-aot.py ์‹คํ–‰ ์‹œ)
    • Native AOT ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ˜ธ์ถœ ์˜ˆ์ œ์— ํ•„์š”
  • Java 17+ ๋ฐ wget (05-native-aot.java ์‹คํ–‰ ์‹œ)
    • Java์—์„œ Native AOT ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ˜ธ์ถœ ์˜ˆ์ œ์— ํ•„์š”
    • JNA(Java Native Access) ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ž๋™ ๋‹ค์šด๋กœ๋“œ
  • Node.js 18+ ๋ฐ npm (05-native-aot.js ์‹คํ–‰ ์‹œ)
    • Node.js์—์„œ Native AOT ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ˜ธ์ถœ ์˜ˆ์ œ์— ํ•„์š”
    • koffi ํŒจํ‚ค์ง€ ์ž๋™ ์„ค์น˜
  • GCC/Clang (05-staticlib-c.c ์ปดํŒŒ์ผ ์‹œ)
    • C ์ปดํŒŒ์ผ๋Ÿฌ ๋ฐ iconv ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
    • macOS: Xcode Command Line Tools (xcode-select --install)
    • Linux: build-essential ํŒจํ‚ค์ง€
  • OpenRouter API ํ‚ค (06-agui-server.cs ์‹คํ–‰ ์‹œ)
    • AI ์—์ด์ „ํŠธ ์˜ˆ์ œ์— ํ•„์š”
    • OpenRouter์—์„œ ๋ฌด๋ฃŒ ๊ณ„์ • ์ƒ์„ฑ ๊ฐ€๋Šฅ

๊ฐœ๋ฐœ ๋„๊ตฌ (๊ถŒ์žฅ)

  • Visual Studio Code + C# Dev Kit ํ™•์žฅ
  • JetBrains Rider
  • Visual Studio 2022 (Windows)
  • LINQPad 8 (์ด ์ €์žฅ์†Œ์˜ ์›๋ž˜ ์‹คํ–‰ ํ™˜๊ฒฝ)

๐Ÿš€ ๋น ๋ฅธ ์‹œ์ž‘

# ์ €์žฅ์†Œ ํด๋ก 
git clone <repository-url>
cd csharp-fba-zero-to-hero

# ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ์˜ˆ์ œ ์‹คํ–‰
chmod +x 01-shell-standard.cs
./01-shell-standard.cs

# ์›น API ์˜ˆ์ œ ์‹คํ–‰
chmod +x 02-random-webapi.cs
./02-random-webapi.cs
# ๋‹ค๋ฅธ ํ„ฐ๋ฏธ๋„์—์„œ: curl http://localhost:5000/

๐Ÿ“š C# ์˜ˆ์ œ ์„ค๋ช…

๊ฐ ์˜ˆ์ œ๋Š” FBA์˜ ํŠน์ • ๊ธฐ๋Šฅ๊ณผ ์‹ค์ œ ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ๋‚œ์ด๋„ ์ˆœ์œผ๋กœ ์ •๋ ฌ๋˜์–ด ์žˆ์œผ๋ฉฐ, ๊ธฐ์ดˆ๋ถ€ํ„ฐ ๊ณ ๊ธ‰ ์ฃผ์ œ๊นŒ์ง€ ๋‹ค๋ฃน๋‹ˆ๋‹ค.

01. Shell Scripts

๐ŸŽ“ ํ•™์Šต ๋ชฉํ‘œ: FBA์˜ ๊ธฐ๋ณธ Shebang ์‚ฌ์šฉ๋ฒ•๊ณผ ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰ ๋ฐฉ์‹ ์ดํ•ด

๊ฐ„๋‹จํ•œ "Hello World" ์Šคํƒ€์ผ์˜ ์‰˜ ์Šคํฌ๋ฆฝํŠธ ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค. C# ํŒŒ์ผ์„ Unix/Linux ์Šคํƒ€์ผ์˜ ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ์Šคํฌ๋ฆฝํŠธ๋กœ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ๊ฐœ๋…:

  • Shebang(#!)์„ ์‚ฌ์šฉํ•œ ์ธํ„ฐํ”„๋ฆฌํ„ฐ ์ง€์ •
  • ์‹คํ–‰ ๊ถŒํ•œ ๋ถ€์—ฌ (chmod +x)
  • ์ง์ ‘ ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ C# ํŒŒ์ผ

01-shell-standard.cs

ํ‘œ์ค€ shebang ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•œ ๊ธฐ๋ณธ ์Šคํฌ๋ฆฝํŠธ์ž…๋‹ˆ๋‹ค.

์‹คํ–‰ ๋ฐฉ๋ฒ•:

# ์‹คํ–‰ ๊ถŒํ•œ ๋ถ€์—ฌ
chmod +x 01-shell-standard.cs

# ์‹คํ–‰
./01-shell-standard.cs

์ถœ๋ ฅ:

No lemon, no melon.

01-shell-alt.cs

๋Œ€์ฒด shebang ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•œ ์Šคํฌ๋ฆฝํŠธ์ž…๋‹ˆ๋‹ค. ์ด ๋ฐฉ์‹์€ JBang์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹๊ณผ ๊ฐ™์€ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.

์‹คํ–‰ ๋ฐฉ๋ฒ•:

# ์‹คํ–‰ ๊ถŒํ•œ ๋ถ€์—ฌ
chmod +x 01-shell-alt.cs

# ์‹คํ–‰
./01-shell-alt.cs

์ถœ๋ ฅ:

No lemon, No melon.

02. Web API

๐ŸŽ“ ํ•™์Šต ๋ชฉํ‘œ: FBA์—์„œ ASP.NET Core ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ž‘์„ฑ ๋ฐฉ๋ฒ•, SDK ์ง€์ • ๋ฐ ์˜์กด์„ฑ ์ฃผ์ž… ์ดํ•ด

ASP.NET Core๋ฅผ ์‚ฌ์šฉํ•œ ๊ฐ„๋‹จํ•œ ์›น API ์„œ๋ฒ„์ž…๋‹ˆ๋‹ค. ๋žœ๋ค ์ˆซ์ž๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์—”๋“œํฌ์ธํŠธ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ๊ฐœ๋…:

  • #:sdk Microsoft.NET.Sdk.Web - Web SDK ์‚ฌ์šฉ
  • #:property PublishAot=false - AOT ์ปดํŒŒ์ผ ๋น„ํ™œ์„ฑํ™”
  • Minimal API ํŒจํ„ด
  • Dependency Injection (DI)
  • Singleton ์„œ๋น„์Šค ๋“ฑ๋ก (Random.Shared)

02-random-webapi.cs

์‹คํ–‰ ๋ฐฉ๋ฒ•:

# ์‹คํ–‰ ๊ถŒํ•œ ๋ถ€์—ฌ
chmod +x 02-random-webapi.cs

# ์‹คํ–‰
./02-random-webapi.cs

ํ…Œ์ŠคํŠธ:

# ๋‹ค๋ฅธ ํ„ฐ๋ฏธ๋„์—์„œ ์‹คํ–‰
curl http://localhost:5000/

์‘๋‹ต ์˜ˆ์‹œ:

{
  "ts": "2025-11-26T12:34:56.7890123Z",
  "val": 7
}

03. Aspire App Host

๐ŸŽ“ ํ•™์Šต ๋ชฉํ‘œ: .NET Aspire๋ฅผ ์‚ฌ์šฉํ•œ ๋ถ„์‚ฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ตฌ์ถ•, ์„œ๋น„์Šค ๊ฐ„ ํ†ต์‹  ๋ฐ ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜

.NET Aspire๋ฅผ ์‚ฌ์šฉํ•œ ๋ถ„์‚ฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜ ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค. Garnet(Redis ํ˜ธํ™˜) ์บ์‹œ ์„œ๋ฒ„, Worker ์„œ๋น„์Šค, Minimal API๋ฅผ ํ•จ๊ป˜ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ๊ฐœ๋…:

  • #:sdk Aspire.AppHost.Sdk - Aspire AppHost SDK ์‚ฌ์šฉ
  • #:package ๋””๋ ‰ํ‹ฐ๋ธŒ๋กœ NuGet ํŒจํ‚ค์ง€ ์ฐธ์กฐ
  • ์„œ๋น„์Šค ๋””์Šค์ปค๋ฒ„๋ฆฌ ๋ฐ ์ฐธ์กฐ ๊ด€๋ฆฌ
  • WaitFor ํŒจํ„ด์œผ๋กœ ์„œ๋น„์Šค ์‹œ์ž‘ ์ˆœ์„œ ์ œ์–ด
  • User Secrets๋ฅผ ํ†ตํ•œ ๋น„๋ฐ€ ์ •๋ณด ๊ด€๋ฆฌ
  • Aspire Dashboard๋ฅผ ํ†ตํ•œ ๋ถ„์‚ฐ ์ถ”์  ๋ฐ ๋ชจ๋‹ˆํ„ฐ๋ง

๊ตฌ์„ฑ ์š”์†Œ

  • 03-apphost.cs: ์•ฑ ํ˜ธ์ŠคํŠธ - ์ „์ฒด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ดํ„ฐ
  • 03-minapi.cs: Minimal API - Redis์—์„œ ๋ฉ”์‹œ์ง€๋ฅผ ์ฝ์–ด ๋ฐ˜ํ™˜ํ•˜๋Š” ์›น API
  • 03-worker.cs: Background Worker - 1์ดˆ๋งˆ๋‹ค Redis์— ํ˜„์žฌ ์‹œ๊ฐ„์„ ์—…๋ฐ์ดํŠธ
  • 03-apphost.json: ์•ฑ ํ˜ธ์ŠคํŠธ ์„ค์ • ํŒŒ์ผ

์‹คํ–‰ ๋ฐฉ๋ฒ•:

# ์‹คํ–‰ ๊ถŒํ•œ ๋ถ€์—ฌ
chmod +x 03-apphost.cs

# ์‹คํ–‰
./03-apphost.cs

ํŠน์ง•:

  • Aspire Dashboard๊ฐ€ ์ž๋™์œผ๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค (http://localhost:18888)
  • Garnet (Redis ํ˜ธํ™˜) ์บ์‹œ ์„œ๋ฒ„๊ฐ€ ์ž๋™์œผ๋กœ ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค
  • Worker๊ฐ€ 1์ดˆ๋งˆ๋‹ค LastUpdated ํ‚ค๋ฅผ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค
  • Minimal API๊ฐ€ ๋ฉ”์‹œ์ง€์™€ ๋งˆ์ง€๋ง‰ ์—…๋ฐ์ดํŠธ ์‹œ๊ฐ„์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค

ํ…Œ์ŠคํŠธ:

# Aspire Dashboard์—์„œ minapi์˜ ํฌํŠธ ํ™•์ธ ํ›„
curl http://localhost:<minapi-port>/

์•„ํ‚คํ…์ฒ˜ ํ๋ฆ„:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   Worker    โ”‚โ”€โ”€โ”€โ”€โ”€>โ”‚   Garnet    โ”‚<โ”€โ”€โ”€โ”€โ”€โ”‚   MinAPI    โ”‚
โ”‚ (03-worker) โ”‚ writeโ”‚  (Redis)    โ”‚ read โ”‚ (03-minapi) โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
      โ†“                                           โ†“
  ๋งค 1์ดˆ๋งˆ๋‹ค                               HTTP ์š”์ฒญ ์‹œ
 LastUpdated ์—…๋ฐ์ดํŠธ                    ๋ฉ”์‹œ์ง€ ์กฐํšŒ ๋ฐ ๋ฐ˜ํ™˜

04. Avalonia GUI

๐ŸŽ“ ํ•™์Šต ๋ชฉํ‘œ: FBA์—์„œ ํฌ๋กœ์Šค ํ”Œ๋žซํผ GUI ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ž‘์„ฑ, MVVM ํŒจํ„ด ์ ์šฉ

Avalonia UI๋ฅผ ์‚ฌ์šฉํ•œ ํฌ๋กœ์Šค ํ”Œ๋žซํผ ๋ฐ์Šคํฌํ†ฑ ๊ณ„์‚ฐ๊ธฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ž…๋‹ˆ๋‹ค. WPF์™€ ์œ ์‚ฌํ•œ XAML ๊ธฐ๋ฐ˜ UI๋ฅผ ์ฝ”๋“œ๋กœ ๊ตฌํ˜„ํ•œ ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ๊ฐœ๋…:

  • #:property OutputType=WinExe - Windows ์‹คํ–‰ ํŒŒ์ผ๋กœ ๋นŒ๋“œ
  • Avalonia UI ํ”„๋ ˆ์ž„์›Œํฌ
  • MVVM (Model-View-ViewModel) ํŒจํ„ด
  • CommunityToolkit.Mvvm์„ ํ™œ์šฉํ•œ ๊ด€์ฐฐ ๊ฐ€๋Šฅ ์†์„ฑ
  • RelayCommand๋ฅผ ํ†ตํ•œ ์ปค๋งจ๋“œ ํŒจํ„ด
  • Dependency Injection๊ณผ ์„œ๋น„์Šค ์ƒ๋ช…์ฃผ๊ธฐ
  • ์ฝ”๋“œ ๊ธฐ๋ฐ˜ UI ๊ตฌ์„ฑ (Code-behind UI)

04-avalonia.cs

์‹คํ–‰ ๋ฐฉ๋ฒ•:

# ์‹คํ–‰ ๊ถŒํ•œ ๋ถ€์—ฌ
chmod +x 04-avalonia.cs

# ์‹คํ–‰
./04-avalonia.cs

ํŠน์ง•:

  • CommunityToolkit.Mvvm์„ ์‚ฌ์šฉํ•œ MVVM ํŒจํ„ด ๊ตฌํ˜„
  • ๊ธฐ๋ณธ ์‚ฌ์น™์—ฐ์‚ฐ ๊ธฐ๋Šฅ (+, -, ร—, รท)
  • ํฌ๋กœ์Šค ํ”Œ๋žซํผ ์ง€์› (Windows, macOS, Linux)
  • Dependency Injection์„ ํ™œ์šฉํ•œ ์„œ๋น„์Šค ๊ตฌ์กฐ

05. Native AOT

๐ŸŽ“ ํ•™์Šต ๋ชฉํ‘œ: Native AOT ์ปดํŒŒ์ผ์„ ํ†ตํ•œ ๋„ค์ดํ‹ฐ๋ธŒ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ƒ์„ฑ, ๋‹ค๋ฅธ ์–ธ์–ด์™€์˜ ์ƒํ˜ธ์šด์šฉ์„ฑ

Native AOT ์ปดํŒŒ์ผ์„ ํ†ตํ•ด C# ์ฝ”๋“œ๋ฅผ ๋„ค์ดํ‹ฐ๋ธŒ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ๋ณ€ํ™˜ํ•˜๊ณ  ๋‹ค์–‘ํ•œ ์–ธ์–ด(Python, C)์—์„œ ํ˜ธ์ถœํ•˜๋Š” ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค. C#์˜ ์„ฑ๋Šฅ๊ณผ ๋‹ค๋ฅธ ์–ธ์–ด์˜ ์œ ์—ฐ์„ฑ์„ ๊ฒฐํ•ฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ๊ฐœ๋…:

  • #:property PublishAot=True - Native AOT ์ปดํŒŒ์ผ ํ™œ์„ฑํ™”
  • #:property OutputType=Library - ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ๋นŒ๋“œ
  • #:property NativeLib=Static - ์ •์  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ƒ์„ฑ
  • #:property RuntimeIdentifier=osx-arm64 - ํƒ€๊ฒŸ ํ”Œ๋žซํผ ์ง€์ •
  • UnmanagedCallersOnly ์†์„ฑ - ๋„ค์ดํ‹ฐ๋ธŒ ํ•จ์ˆ˜ ๋…ธ์ถœ
  • P/Invoke ์—ญ๋ฐฉํ–ฅ (C#์—์„œ ๋„ค์ดํ‹ฐ๋ธŒ๋กœ)
  • ์–ธ์–ด ๊ฐ„ ์ƒํ˜ธ์šด์šฉ์„ฑ (C# โ†” Python/C)
  • ์œ ๋‹ˆ์ฝ”๋“œ ๋ฌธ์ž์—ด ๋งˆ์ƒฌ๋ง
  • iconv๋ฅผ ํ†ตํ•œ UTF-8 โ†” UTF-16 ๋ณ€ํ™˜

์˜ˆ์ œ ํŒŒ์ผ

  • 05-native-aot.cs: C# ๋„ค์ดํ‹ฐ๋ธŒ ๋™์  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์†Œ์Šค (.dylib)
  • 05-native-aot.py: Python์—์„œ ๋™์  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ˜ธ์ถœ ์˜ˆ์ œ
  • 05-native-aot.java: Java์—์„œ ๋™์  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ˜ธ์ถœ ์˜ˆ์ œ (JNA ์‚ฌ์šฉ)
  • 05-native-aot.js: Node.js์—์„œ ๋™์  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ˜ธ์ถœ ์˜ˆ์ œ (koffi ์‚ฌ์šฉ)
  • 05-staticlib-aot.cs: C# ๋„ค์ดํ‹ฐ๋ธŒ ์ •์  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์†Œ์Šค (.a)
  • 05-staticlib-c.c: C์—์„œ ๋™์  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ˜ธ์ถœ ์˜ˆ์ œ

๋™์  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ (.dylib) ์˜ˆ์ œ

๋นŒ๋“œ ๋ฐฉ๋ฒ•:

# C# ์ฝ”๋“œ๋ฅผ ๋„ค์ดํ‹ฐ๋ธŒ ๋™์  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ์ปดํŒŒ์ผ
dotnet publish ./05-native-aot.cs

Python์—์„œ ์‚ฌ์šฉ:

# ์‹คํ–‰ ๊ถŒํ•œ ๋ถ€์—ฌ
chmod +x 05-native-aot.py

# ์‹คํ–‰
./05-native-aot.py

C์—์„œ ์‚ฌ์šฉ:

# ์ปดํŒŒ์ผ ๋ฐ ์‹คํ–‰
gcc -o 05-staticlib-c 05-staticlib-c.c artifacts/05-native-aot/05-native-aot.dylib -Wl,-rpath,artifacts/05-native-aot -liconv
./05-staticlib-c

Java์—์„œ ์‚ฌ์šฉ:

# JNA ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋‹ค์šด๋กœ๋“œ (์ตœ์ดˆ 1ํšŒ)
wget -nc https://repo1.maven.org/maven2/net/java/dev/jna/jna/5.14.0/jna-5.14.0.jar

# ์ปดํŒŒ์ผ
javac -cp jna-5.14.0.jar 05-native-aot.java

# ์‹คํ–‰
java -cp .:jna-5.14.0.jar NativeAotExample

Node.js์—์„œ ์‚ฌ์šฉ:

# koffi ํŒจํ‚ค์ง€ ์„ค์น˜ (์ตœ์ดˆ 1ํšŒ)
npm install koffi

# ์‹คํ–‰ ๊ถŒํ•œ ๋ถ€์—ฌ
chmod +x 05-native-aot.js

# ์‹คํ–‰
./05-native-aot.js
# ๋˜๋Š”
node 05-native-aot.js

์ถœ๋ ฅ ์˜ˆ์‹œ:

Testing Native AOT library from Node.js
==========================================

2025. 11. 26. ์˜คํ›„ 11:56:52 Hello from Node.js!
2025. 11. 26. ์˜คํ›„ 11:56:52 Native AOT ํ˜ธ์ถœ ํ…Œ์ŠคํŠธ
2025. 11. 26. ์˜คํ›„ 11:56:52 ์•ˆ๋…•ํ•˜์„ธ์š”!

All calls completed.

์ •์  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ (.a) ์˜ˆ์ œ

๋นŒ๋“œ ๋ฐฉ๋ฒ•:

# C# ์ฝ”๋“œ๋ฅผ ๋„ค์ดํ‹ฐ๋ธŒ ์ •์  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ์ปดํŒŒ์ผ
dotnet publish ./05-staticlib-aot.cs

โš ๏ธ ์ฐธ๊ณ : ์ •์  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” .NET ๋Ÿฐํƒ€์ž„ ์ข…์†์„ฑ์ด ํฌํ•จ๋˜์ง€ ์•Š์•„ ์ง์ ‘ ๋งํฌ ์‹œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋™์  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(.dylib) ์‚ฌ์šฉ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.

ํŠน์ง•:

  • UnmanagedCallersOnly ์†์„ฑ์„ ์‚ฌ์šฉํ•œ ๋„ค์ดํ‹ฐ๋ธŒ ํ•จ์ˆ˜ ๋…ธ์ถœ
  • Python ctypes, Java JNA, Node.js koffi, C์—์„œ C# ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ˜ธ์ถœ
  • UTF-16 ์œ ๋‹ˆ์ฝ”๋“œ ๋ฌธ์ž์—ด ์ „๋‹ฌ ์ง€์› (ํ•œ๊ธ€ ํฌํ•จ)
  • iconv ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ†ตํ•œ ๊ฐ„๋‹จํ•œ ๋ฌธ์ž ์ธ์ฝ”๋”ฉ ๋ณ€ํ™˜ (C)
  • Java JNA์™€ Node.js koffi๋ฅผ ํ†ตํ•œ ๊ฐ„ํŽธํ•œ ๋„ค์ดํ‹ฐ๋ธŒ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ ‘๊ทผ
  • JIT ์ปดํŒŒ์ผ๋Ÿฌ ์—†์ด ๋น ๋ฅธ ์‹œ์ž‘ ์‹œ๊ฐ„
  • ์ž‘์€ ๋ฐฐํฌ ํฌ๊ธฐ (๋‹จ์ผ ๋„ค์ดํ‹ฐ๋ธŒ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ)
  • .NET ๋Ÿฐํƒ€์ž„ ๋ถˆํ•„์š” (self-contained)

์‚ฌ์šฉ ์‚ฌ๋ก€:

  • Python/Java/Node.js/C ํ”„๋กœ์ ํŠธ์— ๊ณ ์„ฑ๋Šฅ C# ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ†ตํ•ฉ
  • ๋ ˆ๊ฑฐ์‹œ ์‹œ์Šคํ…œ๊ณผ์˜ ์—ฐ๋™
  • ์—ฃ์ง€ ๋””๋ฐ”์ด์Šค์šฉ ๊ฒฝ๋Ÿ‰ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
  • ๊ฒŒ์ž„ ์—”์ง„ ํ”Œ๋Ÿฌ๊ทธ์ธ
  • ์ž„๋ฒ ๋””๋“œ ์‹œ์Šคํ…œ์šฉ ๋„ค์ดํ‹ฐ๋ธŒ ๋ชจ๋“ˆ
  • JVM ๊ธฐ๋ฐ˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ .NET ์ฝ”๋“œ ํ™œ์šฉ
  • Node.js ๋ฐฑ์—”๋“œ์—์„œ ๊ณ ์„ฑ๋Šฅ .NET ๋ชจ๋“ˆ ํ™œ์šฉ

06. AG-UI (AI Agents)

๐ŸŽ“ ํ•™์Šต ๋ชฉํ‘œ: AI ์—์ด์ „ํŠธ ๊ตฌ์ถ•, ์ปค์Šคํ…€ ๋„๊ตฌ ํ†ตํ•ฉ, ์ŠคํŠธ๋ฆฌ๋ฐ ์‘๋‹ต ์ฒ˜๋ฆฌ

Microsoft Agents AI ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•œ AI ์—์ด์ „ํŠธ ์„œ๋ฒ„/ํด๋ผ์ด์–ธํŠธ ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค. OpenAI ํ˜ธํ™˜ API๋ฅผ ํ†ตํ•ด Grok ๋ชจ๋ธ์„ ํ™œ์šฉํ•˜๋ฉฐ, ์ปค์Šคํ…€ ๋„๊ตฌ(Function Calling)๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ๊ฐœ๋…:

  • Microsoft.Agents.AI ํ”„๋ ˆ์ž„์›Œํฌ

  • AG-UI (Agent Gateway User Interface) ํ”„๋กœํ† ์ฝœ

  • OpenAI ํ˜ธํ™˜ API ์‚ฌ์šฉ (OpenRouter๋ฅผ ํ†ตํ•œ Grok ์ ‘๊ทผ)

  • Function Calling / Tool Use ํŒจํ„ด

  • AIFunctionFactory๋ฅผ ํ†ตํ•œ ํ•จ์ˆ˜ ๋“ฑ๋ก

  • ์ŠคํŠธ๋ฆฌ๋ฐ ์‘๋‹ต ์ฒ˜๋ฆฌ

  • User Secrets๋ฅผ ํ†ตํ•œ API ํ‚ค ๊ด€๋ฆฌ

  • IChatClient ์ธํ„ฐํŽ˜์ด์Šค ํ™œ์šฉ

  • 06-agui-server.cs: AG-UI ์„œ๋ฒ„ - AI ์—์ด์ „ํŠธ ํ˜ธ์ŠคํŒ…

  • 06-agui-client.cs: AG-UI ํด๋ผ์ด์–ธํŠธ - ์—์ด์ „ํŠธ์™€ ๋Œ€ํ™”

์„œ๋ฒ„ ์„ค์ •:

# OpenRouter API ํ‚ค ์„ค์ •
dotnet user-secrets --id 06-agui-server set openrouter-key "YOUR_API_KEY_HERE"

์„œ๋ฒ„ ์‹คํ–‰:

# ์‹คํ–‰ ๊ถŒํ•œ ๋ถ€์—ฌ
chmod +x 06-agui-server.cs

# ์‹คํ–‰
./06-agui-server.cs

ํด๋ผ์ด์–ธํŠธ ์‹คํ–‰:

# ์ƒˆ ํ„ฐ๋ฏธ๋„์—์„œ
chmod +x 06-agui-client.cs

# ์‹คํ–‰
./06-agui-client.cs

ํŠน์ง•:

  • OpenAI ํ˜ธํ™˜ API๋ฅผ ํ†ตํ•œ Grok 4.1 ๋ชจ๋ธ ์‚ฌ์šฉ
  • ์ปค์Šคํ…€ ๋„๊ตฌ(Tools) ์ง€์› (๋ง์…ˆ, ๋บ„์…ˆ)
  • ์ŠคํŠธ๋ฆฌ๋ฐ ์‘๋‹ต ์ง€์›
  • ๋Œ€ํ™”ํ˜• CLI ์ธํ„ฐํŽ˜์ด์Šค

์‚ฌ์šฉ ์˜ˆ์‹œ:

User (:q or quit to exit): 25 ๋”ํ•˜๊ธฐ 17์€?
[Run Started - Thread: xxx, Run: yyy]
25 ๋”ํ•˜๊ธฐ 17์€ 42์ž…๋‹ˆ๋‹ค.
[Run Finished - Thread: xxx]

User (:q or quit to exit): :q

07. Blazor WebAssembly

๐ŸŽ“ ํ•™์Šต ๋ชฉํ‘œ: FBA์—์„œ Blazor WebAssembly ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ž‘์„ฑ, ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ SPA ๊ตฌ์ถ•

Blazor WebAssembly๋ฅผ ์‚ฌ์šฉํ•œ ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ ๋‹จ์ผ ํŽ˜์ด์ง€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜(SPA) ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ง์ ‘ ์‹คํ–‰๋˜๋Š” .NET ๊ธฐ๋ฐ˜ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ FBA ํ˜•ํƒœ๋กœ ์ž‘์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ๊ฐœ๋…:

  • #:sdk Microsoft.NET.Sdk.BlazorWebAssembly - Blazor WebAssembly SDK ์‚ฌ์šฉ
  • #:property OverrideHtmlAssetPlaceholders=true - HTML ์ž์‚ฐ ํ”Œ๋ ˆ์ด์Šคํ™€๋” ์žฌ์ •์˜
  • #:property RootNamespace=app - ๋ฃจํŠธ ๋„ค์ž„์ŠคํŽ˜์ด์Šค ์ง€์ •
  • Razor ์ปดํฌ๋„ŒํŠธ ๊ธฐ๋ฐ˜ UI ๊ตฌ์„ฑ
  • ๋ผ์šฐํŒ… ๋ฐ ๋ ˆ์ด์•„์›ƒ ์‹œ์Šคํ…œ
  • HttpClient๋ฅผ ํ†ตํ•œ ๋ฐ์ดํ„ฐ ํŽ˜์นญ
  • MD2RazorGenerator๋ฅผ ํ™œ์šฉํ•œ Markdown ํŽ˜์ด์ง€ ์ง€์›

๊ตฌ์„ฑ ์š”์†Œ

  • 07-blazor-wasm/app.cs: ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ง„์ž…์  - WebAssemblyHostBuilder ์„ค์ •
  • 07-blazor-wasm/App.razor: ๋ฃจํŠธ ์ปดํฌ๋„ŒํŠธ - ๋ผ์šฐํ„ฐ ๊ตฌ์„ฑ
  • 07-blazor-wasm/_Imports.razor: ์ „์—ญ using ์„ ์–ธ
  • 07-blazor-wasm/Layout/: ๋ ˆ์ด์•„์›ƒ ์ปดํฌ๋„ŒํŠธ (MainLayout, NavMenu)
  • 07-blazor-wasm/Pages/: ํŽ˜์ด์ง€ ์ปดํฌ๋„ŒํŠธ (Home, Counter, Weather)
  • 07-blazor-wasm/wwwroot/: ์ •์  ์ž์‚ฐ (CSS, ์ƒ˜ํ”Œ ๋ฐ์ดํ„ฐ)

ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ

07-blazor-wasm/
โ”œโ”€โ”€ app.cs                 # ์ง„์ž…์  (FBA ๋ฉ”์ธ ํŒŒ์ผ)
โ”œโ”€โ”€ App.razor              # ๋ฃจํŠธ ์ปดํฌ๋„ŒํŠธ
โ”œโ”€โ”€ _Imports.razor         # ์ „์—ญ using
โ”œโ”€โ”€ Layout/
โ”‚   โ”œโ”€โ”€ MainLayout.razor   # ๋ฉ”์ธ ๋ ˆ์ด์•„์›ƒ
โ”‚   โ””โ”€โ”€ NavMenu.razor      # ๋„ค๋น„๊ฒŒ์ด์…˜ ๋ฉ”๋‰ด
โ”œโ”€โ”€ Pages/
โ”‚   โ”œโ”€โ”€ Home.md            # ํ™ˆ ํŽ˜์ด์ง€ (Markdown)
โ”‚   โ”œโ”€โ”€ Counter.razor      # ์นด์šดํ„ฐ ์˜ˆ์ œ
โ”‚   โ”œโ”€โ”€ Weather.razor      # ๋‚ ์”จ ๋ฐ์ดํ„ฐ ํŽ˜์นญ ์˜ˆ์ œ
โ”‚   โ””โ”€โ”€ NotFound.razor     # 404 ํŽ˜์ด์ง€
โ””โ”€โ”€ wwwroot/
    โ”œโ”€โ”€ index.html         # HTML ํ˜ธ์ŠคํŠธ ํŽ˜์ด์ง€
    โ”œโ”€โ”€ css/               # ์Šคํƒ€์ผ์‹œํŠธ
    โ””โ”€โ”€ sample-data/       # JSON ์ƒ˜ํ”Œ ๋ฐ์ดํ„ฐ

์‹คํ–‰ ๋ฐฉ๋ฒ•:

# 07-blazor-wasm ํด๋”๋กœ ์ด๋™
cd 07-blazor-wasm

# ์‹คํ–‰ (--no-cache ์˜ต์…˜ ํ•„์ˆ˜)
dotnet run --no-cache app.cs

โš ๏ธ ์ค‘์š”: Blazor WebAssembly FBA๋Š” ์—ฌ๋Ÿฌ Razor ํŒŒ์ผ๊ณผ ์ •์  ์ž์‚ฐ์„ ํฌํ•จํ•˜๋ฏ€๋กœ, ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋ฐ˜์˜๋˜๋ ค๋ฉด ๋ฐ˜๋“œ์‹œ --no-cache ์˜ต์…˜์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ์˜ต์…˜ ์—†์ด ์‹คํ–‰ํ•˜๋ฉด ์ด์ „ ์บ์‹œ๋œ ๋นŒ๋“œ๊ฐ€ ์‚ฌ์šฉ๋˜์–ด ์ตœ์‹  ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์ ์šฉ๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํŠน์ง•:

  • ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ง์ ‘ ์‹คํ–‰๋˜๋Š” .NET ์ฝ”๋“œ (WebAssembly)
  • ์„œ๋ฒ„ ์—†์ด ์ •์  ํ˜ธ์ŠคํŒ… ๊ฐ€๋Šฅ (GitHub Pages, Azure Static Web Apps ๋“ฑ)
  • Bootstrap ๊ธฐ๋ฐ˜ ๋ฐ˜์‘ํ˜• UI
  • Markdown ํŒŒ์ผ์„ ํŽ˜์ด์ง€๋กœ ๋ณ€ํ™˜ (MD2RazorGenerator)
  • ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ ๋ผ์šฐํŒ…
  • HttpClient๋ฅผ ํ†ตํ•œ JSON ๋ฐ์ดํ„ฐ ๋กœ๋”ฉ

ํŽ˜์ด์ง€ ์„ค๋ช…:

ํŽ˜์ด์ง€ ๊ฒฝ๋กœ ์„ค๋ช…
Home /, /home Markdown์œผ๋กœ ์ž‘์„ฑ๋œ ํ™ˆ ํŽ˜์ด์ง€
Counter /counter ๋ฒ„ํŠผ ํด๋ฆญ ์นด์šดํ„ฐ ์˜ˆ์ œ
Weather /weather JSON ํŒŒ์ผ์—์„œ ๋‚ ์”จ ๋ฐ์ดํ„ฐ ๋กœ๋”ฉ

๋„ค์ž„์ŠคํŽ˜์ด์Šค ๋ณ€๊ฒฝ ์‹œ ์ฃผ์˜์‚ฌํ•ญ:

๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด ๋‹ค์Œ ํŒŒ์ผ๋“ค์„ ํ•จ๊ป˜ ์ˆ˜์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค:

  1. app.cs: using ๋ฌธ์˜ ๋„ค์ž„์ŠคํŽ˜์ด์Šค
  2. _Imports.razor: @using ์ง€์‹œ๋ฌธ์˜ ๋„ค์ž„์ŠคํŽ˜์ด์Šค
  3. wwwroot/index.html: <namespace>.styles.css ์ฐธ์กฐ

๋ณ€๊ฒฝ ํ›„ ๋ฐ˜๋“œ์‹œ dotnet run --no-cache app.cs๋กœ ์‹คํ–‰ํ•˜์„ธ์š”.

์•„ํ‚คํ…์ฒ˜:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                      Browser                            โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚              Blazor WebAssembly App               โ”‚  โ”‚
โ”‚  โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚  โ”‚
โ”‚  โ”‚  โ”‚ Router  โ”‚โ”€โ”€โ”‚ Layout  โ”‚โ”€โ”€โ”‚     Pages       โ”‚   โ”‚  โ”‚
โ”‚  โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚ - Home.md       โ”‚   โ”‚  โ”‚
โ”‚  โ”‚       โ”‚            โ”‚       โ”‚ - Counter.razor โ”‚   โ”‚  โ”‚
โ”‚  โ”‚       โ”‚            โ”‚       โ”‚ - Weather.razor โ”‚   โ”‚  โ”‚
โ”‚  โ”‚       โ–ผ            โ–ผ       โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚  โ”‚
โ”‚  โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                 โ”‚  โ”‚
โ”‚  โ”‚  โ”‚     .NET WebAssembly        โ”‚                 โ”‚  โ”‚
โ”‚  โ”‚  โ”‚   (dotnet.native.wasm)      โ”‚                 โ”‚  โ”‚
โ”‚  โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                 โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚                         โ”‚                               โ”‚
โ”‚                         โ–ผ                               โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚              wwwroot (Static Assets)              โ”‚  โ”‚
โ”‚  โ”‚         index.html, CSS, sample-data/             โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿ“š F# ์˜ˆ์ œ ์„ค๋ช…

๊ฐ ์˜ˆ์ œ๋Š” FBA์˜ ํŠน์ • ๊ธฐ๋Šฅ๊ณผ ์‹ค์ œ ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ๋‚œ์ด๋„ ์ˆœ์œผ๋กœ ์ •๋ ฌ๋˜์–ด ์žˆ์œผ๋ฉฐ, ๊ธฐ์ดˆ๋ถ€ํ„ฐ ๊ณ ๊ธ‰ ์ฃผ์ œ๊นŒ์ง€ ๋‹ค๋ฃน๋‹ˆ๋‹ค.

01. Shell Scripts (F#)

๐ŸŽ“ ํ•™์Šต ๋ชฉํ‘œ: F# ์Šคํฌ๋ฆฝํŠธ(.fsx)์˜ Shebang ์‚ฌ์šฉ๋ฒ•๊ณผ dotnet fsi๋กœ ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ์‹ ์ดํ•ด

๊ฐ„๋‹จํ•œ "Hello World" ์Šคํƒ€์ผ์˜ ์‰˜ ์Šคํฌ๋ฆฝํŠธ ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค. F# ์Šคํฌ๋ฆฝํŠธ(.fsx)๋ฅผ Unix/Linux ์Šคํƒ€์ผ์˜ ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ์Šคํฌ๋ฆฝํŠธ๋กœ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ๊ฐœ๋…:

  • Shebang(#!)์œผ๋กœ dotnet fsi(F# Interactive) ์ง€์ • (#!/usr/bin/env -S dotnet fsi)
  • ์‹คํ–‰ ๊ถŒํ•œ ๋ถ€์—ฌ (chmod +x)
  • ์ง์ ‘ ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ F# ์Šคํฌ๋ฆฝํŠธ
  • F# ๋‚ด์žฅ ๊ฐ’: __SOURCE_FILE__, __SOURCE_DIRECTORY__๋กœ ์Šคํฌ๋ฆฝํŠธ ๊ฒฝ๋กœ ํ™œ์šฉ
  • printfn์„ ์ด์šฉํ•œ ์ถœ๋ ฅ

01-shell-standard.fsx

ํ‘œ์ค€ shebang ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•œ ๊ธฐ๋ณธ F# ์Šคํฌ๋ฆฝํŠธ์ž…๋‹ˆ๋‹ค.

์‹คํ–‰ ๋ฐฉ๋ฒ•:

# ์‹คํ–‰ ๊ถŒํ•œ ๋ถ€์—ฌ
chmod +x 01-shell-standard.fsx

# ์‹คํ–‰
./01-shell-standard.fsx

์ถœ๋ ฅ:

No lemon, no melon.
File: (ํ˜„์žฌ ์Šคํฌ๋ฆฝํŠธ ๊ฒฝ๋กœ)
Directory: (ํ˜„์žฌ ์Šคํฌ๋ฆฝํŠธ ๋””๋ ‰ํ„ฐ๋ฆฌ)

02. Web API (F#)

๐ŸŽ“ ํ•™์Šต ๋ชฉํ‘œ: F# .fsx ์Šคํฌ๋ฆฝํŠธ์—์„œ #r "nuget: ..."๋กœ ํŒจํ‚ค์ง€ ์ฐธ์กฐ, Suave๋กœ ๊ฒฝ๋Ÿ‰ ์›น API ์ž‘์„ฑ

F# .fsx์—์„œ๋Š” ASP.NET Core์˜ FrameworkReference๋ฅผ ์“ธ ์ˆ˜ ์—†์œผ๋ฏ€๋กœ, ๊ฒฝ๋Ÿ‰ ์›น ํ”„๋ ˆ์ž„์›Œํฌ Suave๋ฅผ ์‚ฌ์šฉํ•œ ๋žœ๋ค ์ˆซ์ž API ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ๊ฐœ๋…:

  • #r "nuget: Suave", #r "nuget: System.Text.Json" โ€” ์Šคํฌ๋ฆฝํŠธ ๋‚ด NuGet ์ฐธ์กฐ
  • Suave์˜ path/choose/>=> ์ปดํฌ์ง€์…˜์œผ๋กœ ๋ผ์šฐํŒ… ๋ฐ ๋ฏธ๋“ค์›จ์–ด
  • F# ์ต๋ช… ๋ ˆ์ฝ”๋“œ({| ts = ...; val = ... |})๋กœ JSON ์‘๋‹ต ๋ชจ๋ธ๋ง
  • async { ... } (F# ๋น„๋™๊ธฐ ์›Œํฌํ”Œ๋กœ) ํ™œ์šฉ

02-random-webapi.fsx

์‹คํ–‰ ๋ฐฉ๋ฒ•:

# ์‹คํ–‰ ๊ถŒํ•œ ๋ถ€์—ฌ
chmod +x 02-random-webapi.fsx

# ์‹คํ–‰
./02-random-webapi.fsx

ํ…Œ์ŠคํŠธ:

# ๋‹ค๋ฅธ ํ„ฐ๋ฏธ๋„์—์„œ ์‹คํ–‰ (Suave ๊ธฐ๋ณธ ํฌํŠธ 8080)
curl http://localhost:8080/

์‘๋‹ต ์˜ˆ์‹œ:

{
  "ts": "2025-11-26T12:34:56.7890123Z",
  "val": 7
}

03. Aspire App Host (F#)

๐ŸŽ“ ํ•™์Šต ๋ชฉํ‘œ: .NET Aspire๋กœ ๋ถ„์‚ฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ตฌ์ถ•, C# App Host์—์„œ F# ์Šคํฌ๋ฆฝํŠธ(Worker/MinAPI) ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜

.NET Aspire๋ฅผ ์‚ฌ์šฉํ•œ ๋ถ„์‚ฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜ ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค. ์•ฑ ํ˜ธ์ŠคํŠธ๋Š” C#(03-apphost.cs)์ด๋ฉฐ, Garnet(Redis ํ˜ธํ™˜) ์บ์‹œ์™€ ํ•จ๊ป˜ F# ์Šคํฌ๋ฆฝํŠธ WorkerยทMinAPI๋ฅผ AddExecutable๋กœ ๊ธฐ๋™ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ๊ฐœ๋…:

  • 03-apphost.cs: C# FBA โ€” #:sdk Aspire.AppHost.Sdk, #:package๋กœ Garnet ์ฐธ์กฐ
  • ์ธ์ž fsharp ์—ฌ๋ถ€์— ๋”ฐ๋ผ C# ์•ฑ ๋˜๋Š” F# ์Šคํฌ๋ฆฝํŠธ(dotnet fsi 03-worker.fsx / 03-minapi.fsx) ์„ ํƒ
  • F# ์ชฝ: ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ConnectionStrings__cache๋กœ Redis ์—ฐ๊ฒฐ, Async.AwaitTaskยทasync { } ํ™œ์šฉ
  • WaitFor ํŒจํ„ด์œผ๋กœ ์„œ๋น„์Šค ์‹œ์ž‘ ์ˆœ์„œ ์ œ์–ด, User SecretsยทAspire Dashboard

๊ตฌ์„ฑ ์š”์†Œ

  • 03-apphost.cs: ์•ฑ ํ˜ธ์ŠคํŠธ(C#) โ€” ์ „์ฒด ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ดํ„ฐ, fsharp ์ธ์ž ์‹œ F# ์Šคํฌ๋ฆฝํŠธ ๊ธฐ๋™
  • 03-minapi.fsx: F# Suave ์›น API โ€” Redis์—์„œ ๋ฉ”์‹œ์ง€ยทLastUpdated ์ฝ์–ด ๋ฐ˜ํ™˜, PORT/ASPNETCORE_URLS๋กœ ํฌํŠธ ์„ค์ •(๊ธฐ๋ณธ 9080)
  • 03-worker.fsx: F# Worker โ€” 1์ดˆ๋งˆ๋‹ค Redis์— LastUpdated ์—…๋ฐ์ดํŠธ, ์žฌ๊ท€ async ๋ฃจํ”„
  • 03-apphost.json: ์•ฑ ํ˜ธ์ŠคํŠธ ์„ค์ • ํŒŒ์ผ

์‹คํ–‰ ๋ฐฉ๋ฒ•:

# ์‹คํ–‰ ๊ถŒํ•œ ๋ถ€์—ฌ
chmod +x 03-apphost.cs

# F# ์Šคํฌ๋ฆฝํŠธ(Worker + MinAPI)๋กœ ์‹คํ–‰
./03-apphost.cs fsharp

ํŠน์ง•:

  • Aspire Dashboard๊ฐ€ ์ž๋™์œผ๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค (http://localhost:18888)
  • Garnet (Redis ํ˜ธํ™˜) ์บ์‹œ ์„œ๋ฒ„๊ฐ€ ์ž๋™์œผ๋กœ ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค
  • F# Worker๊ฐ€ 1์ดˆ๋งˆ๋‹ค LastUpdated ํ‚ค๋ฅผ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค
  • F# MinAPI๊ฐ€ ๋ฉ”์‹œ์ง€์™€ ๋งˆ์ง€๋ง‰ ์—…๋ฐ์ดํŠธ ์‹œ๊ฐ„์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค (Suave, ํฌํŠธ ๊ธฐ๋ณธ 9080)

ํ…Œ์ŠคํŠธ:

# F# MinAPI ์‚ฌ์šฉ ์‹œ ๊ธฐ๋ณธ ํฌํŠธ 9080
curl http://localhost:9080/

์•„ํ‚คํ…์ฒ˜ ํ๋ฆ„:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   Worker    โ”‚โ”€โ”€โ”€โ”€โ”€>โ”‚   Garnet    โ”‚<โ”€โ”€โ”€โ”€โ”€โ”‚   MinAPI    โ”‚
โ”‚(03-worker   โ”‚ writeโ”‚  (Redis)    โ”‚ read โ”‚(03-minapi   โ”‚
โ”‚   .fsx)     โ”‚      โ”‚             โ”‚      โ”‚   .fsx)     โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
      โ†“                                           โ†“
  ๋งค 1์ดˆ๋งˆ๋‹ค                               HTTP ์š”์ฒญ ์‹œ
 LastUpdated ์—…๋ฐ์ดํŠธ                    ๋ฉ”์‹œ์ง€ ์กฐํšŒ ๋ฐ ๋ฐ˜ํ™˜

04. Avalonia GUI (F#)

๐ŸŽ“ ํ•™์Šต ๋ชฉํ‘œ: F# .fsx์—์„œ Avalonia.FuncUI๋กœ ํฌ๋กœ์Šค ํ”Œ๋žซํผ GUI ์ž‘์„ฑ, MVU(Elmish) ํŒจํ„ด ์ ์šฉ

Avalonia UI์™€ Avalonia.FuncUI๋ฅผ ์‚ฌ์šฉํ•œ ํฌ๋กœ์Šค ํ”Œ๋žซํผ ๋ฐ์Šคํฌํ†ฑ ๊ณ„์‚ฐ๊ธฐ์ž…๋‹ˆ๋‹ค. F#์˜ fsx์—์„œ๋Š” ์†Œ์Šค ์ œ๋„ˆ๋ ˆ์ดํ„ฐ๋ฅผ ์“ฐ๊ธฐ ์–ด๋ ค์šฐ๋ฏ€๋กœ, MVU(Model-View-Update) ํŒจํ„ด์œผ๋กœ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ๊ฐœ๋…:

  • #r "nuget: Avalonia", Avalonia.Desktop, Avalonia.FuncUI โ€” ์Šคํฌ๋ฆฝํŠธ ๋‚ด NuGet ์ฐธ์กฐ
  • MVU (Elmish) โ€” Model ํƒ€์ž…, Msg ๊ตฌ๋ณ„ ํ•ฉ union, init/update/view ํ•จ์ˆ˜
  • ํŒจํ„ด ๋งค์นญ์œผ๋กœ update ๋ถ„๊ธฐ ๋ฐ calculate ๋กœ์ง ํ‘œํ˜„
  • Avalonia.FuncUI DSL (Button.create, Grid.create ๋“ฑ)์œผ๋กœ ์ฝ”๋“œ ๊ธฐ๋ฐ˜ UI
  • Component์™€ ctx.useState๋กœ ์ƒํƒœ ๋ณด๊ด€ ๋ฐ dispatch๋กœ ๋ฉ”์‹œ์ง€ ์ „๋‹ฌ

04-avalonia.fsx

์‹คํ–‰ ๋ฐฉ๋ฒ•:

# ์‹คํ–‰ ๊ถŒํ•œ ๋ถ€์—ฌ
chmod +x 04-avalonia.fsx

# ์‹คํ–‰
./04-avalonia.fsx

ํŠน์ง•:

  • Avalonia.FuncUI + MVU ํŒจํ„ด์œผ๋กœ ๋‹จ๋ฐฉํ–ฅ ๋ฐ์ดํ„ฐ ํ๋ฆ„๊ณผ ๋ถˆ๋ณ€ ๋ชจ๋ธ
  • ๊ธฐ๋ณธ ์‚ฌ์น™์—ฐ์‚ฐ (+, -, ร—, รท), ํ•œ๊ธ€ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€(0์œผ๋กœ ๋‚˜๋ˆ„๊ธฐ ๋“ฑ)
  • ํฌ๋กœ์Šค ํ”Œ๋žซํผ (Windows, macOS, Linux)
  • F# ๊ตฌ๋ณ„ ํ•ฉ union๊ณผ ํŒจํ„ด ๋งค์นญ์„ ํ™œ์šฉํ•œ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ

๐Ÿ“– FBA ๋””๋ ‰ํ‹ฐ๋ธŒ ๊ฐ€์ด๋“œ

FBA์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ฃผ์š” ๋””๋ ‰ํ‹ฐ๋ธŒ๋“ค์ž…๋‹ˆ๋‹ค:

SDK ์ง€์ •

#:sdk Microsoft.NET.Sdk           // ๊ธฐ๋ณธ ์ฝ˜์†” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜
#:sdk Microsoft.NET.Sdk.Web       // ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜
#:sdk Microsoft.NET.Sdk.Worker    // Worker ์„œ๋น„์Šค
#:sdk Microsoft.NET.Sdk.BlazorWebAssembly  // Blazor WebAssembly
#:sdk Aspire.AppHost.Sdk@13.0.0   // Aspire AppHost (๋ฒ„์ „ ์ง€์ •)

ํŒจํ‚ค์ง€ ์ฐธ์กฐ

#:package Newtonsoft.Json                    // ์ตœ์‹  ๋ฒ„์ „
#:package Newtonsoft.Json@13.0.3             // ํŠน์ • ๋ฒ„์ „
#:package Microsoft.Extensions.Hosting@10.*  // ์™€์ผ๋“œ์นด๋“œ ๋ฒ„์ „

๋นŒ๋“œ ์†์„ฑ

#:property OutputType=Library                // ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ๋นŒ๋“œ
#:property OutputType=WinExe                 // Windows ์‹คํ–‰ ํŒŒ์ผ
#:property PublishAot=true                   // Native AOT ํ™œ์„ฑํ™”
#:property PublishAot=false                  // Native AOT ๋น„ํ™œ์„ฑํ™”
#:property RuntimeIdentifier=osx-arm64       // ํƒ€๊ฒŸ ํ”Œ๋žซํผ ์ง€์ •
#:property TargetFramework=net10.0           // ํƒ€๊ฒŸ ํ”„๋ ˆ์ž„์›Œํฌ

Shebang ์Šคํƒ€์ผ

#!/usr/bin/env dotnet              // ํ‘œ์ค€ ๋ฐฉ์‹
///usr/bin/env dotnet "$0" "$@" ; exit $?  // JBang ์Šคํƒ€์ผ

๐Ÿ”ง ๋ฌธ์ œ ํ•ด๊ฒฐ

์‹คํ–‰ ๊ถŒํ•œ ์˜ค๋ฅ˜

๋ฌธ์ œ: Permission denied ์˜ค๋ฅ˜ ๋ฐœ์ƒ

ํ•ด๊ฒฐ:

chmod +x <ํŒŒ์ผ๋ช…>.cs

ํŒจํ‚ค์ง€ ๋ณต์› ์˜ค๋ฅ˜

๋ฌธ์ œ: ํŒจํ‚ค์ง€๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†๊ฑฐ๋‚˜ ๋ฒ„์ „ ์ถฉ๋Œ

ํ•ด๊ฒฐ:

# NuGet ์บ์‹œ ์ •๋ฆฌ
dotnet nuget locals all --clear

# ๋‹ค์‹œ ์‹คํ–‰
./<ํŒŒ์ผ๋ช…>.cs

Native AOT ๋นŒ๋“œ ์‹คํŒจ

๋ฌธ์ œ: Native AOT ์ปดํŒŒ์ผ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ

ํ•ด๊ฒฐ:

  • ํ”Œ๋žซํผ์— ๋งž๋Š” ๋นŒ๋“œ ๋„๊ตฌ ์„ค์น˜ ํ•„์š”
  • macOS: Xcode Command Line Tools (xcode-select --install)
  • Linux: GCC/Clang ๋ฐ ๊ฐœ๋ฐœ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
  • Windows: Visual Studio Build Tools

Aspire Dashboard ์ ‘๊ทผ ๋ถˆ๊ฐ€

๋ฌธ์ œ: Dashboard์— ์—ฐ๊ฒฐํ•  ์ˆ˜ ์—†์Œ

ํ•ด๊ฒฐ:

# ํฌํŠธ ์ถฉ๋Œ ํ™•์ธ
lsof -i :18888

# 03-apphost.json์—์„œ ํฌํŠธ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ

OpenRouter API ํ‚ค ์˜ค๋ฅ˜

๋ฌธ์ œ: openrouter-key is missing ์˜ค๋ฅ˜

ํ•ด๊ฒฐ:

# User Secrets ์„ค์ • ํ™•์ธ
dotnet user-secrets list --id 06-agui-server

# ๋‹ค์‹œ ์„ค์ •
dotnet user-secrets --id 06-agui-server set openrouter-key "your-api-key"

๐Ÿค ๊ธฐ์—ฌํ•˜๊ธฐ

์ด ํ”„๋กœ์ ํŠธ์— ๊ธฐ์—ฌํ•˜๊ณ  ์‹ถ์œผ์‹ ๊ฐ€์š”? ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค!

  1. ์ด ์ €์žฅ์†Œ๋ฅผ Fork ํ•˜์„ธ์š”
  2. Feature ๋ธŒ๋žœ์น˜๋ฅผ ์ƒ์„ฑํ•˜์„ธ์š” (git checkout -b feature/AmazingFeature)
  3. ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ์ปค๋ฐ‹ํ•˜์„ธ์š” (git commit -m 'Add some AmazingFeature')
  4. ๋ธŒ๋žœ์น˜์— Push ํ•˜์„ธ์š” (git push origin feature/AmazingFeature)
  5. Pull Request๋ฅผ ์—ด์–ด์ฃผ์„ธ์š”

๊ธฐ์—ฌ ์•„์ด๋””์–ด:

  • ์ƒˆ๋กœ์šด ์˜ˆ์ œ ์ถ”๊ฐ€ (gRPC, SignalR, Blazor ๋“ฑ)
  • ๊ธฐ์กด ์˜ˆ์ œ ๊ฐœ์„  ๋ฐ ๋ฒ„๊ทธ ์ˆ˜์ •
  • ๋ฌธ์„œ ๋ฒˆ์—ญ (์˜์–ด, ์ผ๋ณธ์–ด ๋“ฑ)
  • ์„ฑ๋Šฅ ์ตœ์ ํ™”
  • ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ถ”๊ฐ€

๐Ÿ“„ ๋ผ์ด์„ ์Šค

์ด ํ”„๋กœ์ ํŠธ๋Š” MIT ๋ผ์ด์„ ์Šค ํ•˜์— ๋ฐฐํฌ๋ฉ๋‹ˆ๋‹ค.

MIT License

Copyright (c) 2025

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

๐Ÿ”— ์ฐธ๊ณ  ์ž๋ฃŒ

๊ณต์‹ ๋ฌธ์„œ

  • .NET File-Based Applications - ๊ณต์‹ FBA ๋ฌธ์„œ
  • .NET 10 Release Notes - ์ตœ์‹  ๊ธฐ๋Šฅ ๋ฐ ๋ณ€๊ฒฝ์‚ฌํ•ญ
  • .NET Aspire Documentation - ํด๋ผ์šฐ๋“œ ๋„ค์ดํ‹ฐ๋ธŒ ์•ฑ ๊ตฌ์ถ•
  • Avalonia UI Documentation - ํฌ๋กœ์Šค ํ”Œ๋žซํผ UI ํ”„๋ ˆ์ž„์›Œํฌ
  • Native AOT Deployment - ๋„ค์ดํ‹ฐ๋ธŒ ์ปดํŒŒ์ผ ๊ฐ€์ด๋“œ

ํ”„๋ ˆ์ž„์›Œํฌ ๋ฐ ๋„๊ตฌ

  • Microsoft Agents AI - AI ์—์ด์ „ํŠธ ํ”„๋ ˆ์ž„์›Œํฌ
  • OpenRouter - ํ†ตํ•ฉ LLM API ๊ฒŒ์ดํŠธ์›จ์ด
  • Garnet - Microsoft์˜ Redis ํ˜ธํ™˜ ์บ์‹œ
  • LINQPad - .NET ๊ฐœ๋ฐœ ๋ฐ ์ฟผ๋ฆฌ ๋„๊ตฌ

์ปค๋ฎค๋‹ˆํ‹ฐ

  • .NET Community - ๊ณต์‹ ์ปค๋ฎค๋‹ˆํ‹ฐ
  • Avalonia Community - Avalonia ์ปค๋ฎค๋‹ˆํ‹ฐ
  • r/dotnet - Reddit ์ปค๋ฎค๋‹ˆํ‹ฐ

๊ด€๋ จ ํ”„๋กœ์ ํŠธ

  • dotnet/runtime - .NET ๋Ÿฐํƒ€์ž„ ์†Œ์Šค์ฝ”๋“œ
  • dotnet/aspire - .NET Aspire ์†Œ์Šค์ฝ”๋“œ
  • AvaloniaUI/Avalonia - Avalonia UI ์†Œ์Šค์ฝ”๋“œ

โญ ์ด ํ”„๋กœ์ ํŠธ๊ฐ€ ๋„์›€์ด ๋˜์…จ๋‹ค๋ฉด Star๋ฅผ ๋ˆŒ๋Ÿฌ์ฃผ์„ธ์š”!

๐Ÿ’ฌ ์งˆ๋ฌธ์ด๋‚˜ ์ œ์•ˆ์‚ฌํ•ญ์ด ์žˆ์œผ์‹œ๋ฉด Issue๋ฅผ ์ƒ์„ฑํ•ด ์ฃผ์„ธ์š”.

About

.NET File-based App Example Codes

Resources

Readme
MIT license
Activity
Custom properties

Stars

10 stars

Watchers

0 watching

Forks

1 fork
Report repository

Releases

Packages

Contributors

Languages

You are visitor 01402520 โ€” GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800ร—600. No cookies required.