2026๋ .NET MAUI ์๋ฒฝ ๊ฐ์ด๋: ํฌ๋ก์ค ํ๋ซํผ ๊ฐ๋ฐ๊ณผ ๋ฉด์ ์ง๋ฌธ ์ ๋ฆฌ
.NET MAUI 10์ผ๋ก ํฌ๋ก์ค ํ๋ซํผ ์ฑ์ ๊ตฌ์ถํ๋ ๋ฐฉ๋ฒ์ ํธ๋ค๋ฌ ์ํคํ ์ฒ, MVVM, HybridWebView, SafeAreaEdges์ ํจ๊ป ๋ค๋ฃจ๊ณ , 2026๋ ๊ธฐ์ ๋ฉด์ ํต์ฌ ์ง๋ฌธ์ ์ ๋ฆฌํฉ๋๋ค.

.NET MAUI(Multi-platform App UI)๋ .NET 10๊ณผ ํจ๊ป ํ๋ก๋์ ์์ค์ ํฌ๋ก์ค ํ๋ซํผ ํ๋ ์์ํฌ๋ก ์์ ํ ์ฑ์ํ ๋จ๊ณ์ ์ ์ด๋ค์์ต๋๋ค. 2028๋ 11์๊น์ง ์ง์๋๋ LTS(Long-Term Support) ๋ฆด๋ฆฌ์ค๋ก ์ถ์๋ .NET MAUI 10์ ์ํฌ๋ก๋ ๋ฐ NuGet ํจํค์ง ํํ๋ก ๋ฐฐํฌ๋๋ฉฐ, ํ์ง ๊ฐ์ , ์ฑ๋ฅ ํฅ์, HybridWebView ๊ฐํ ๋ฐ SafeAreaEdges ๊ฐ์ ์ ๊ท API๋ฅผ ์ ๊ณตํฉ๋๋ค. ์ด ๊ธ์์๋ ํฌ๋ก์ค ํ๋ซํผ ์ฑ ๊ตฌ์ถ ๊ณผ์ ์ ๋จ๊ณ๋ณ๋ก ์ดํด๋ณด๊ณ , MAUI์ ํต์ฌ ์ํคํ ์ฒ๋ฅผ ๋ถ์ํ๋ฉฐ, 2026๋ ์ฑ์ฉ ํ์ฅ์์ ์ค์ ๋ก ์ถ์ ๋๋ ๋ฉด์ ์ง๋ฌธ์ ๋ค๋ฃน๋๋ค.
.NET 10์ 2028๋ 11์๊น์ง ์ง์๋๋ ์ฅ๊ธฐ ์ง์(LTS) ๋ฆด๋ฆฌ์ค์ ๋๋ค. MAUI 10์ ์๋ก์ด UI ์ปจํธ๋กค ์ถ๊ฐ๋ณด๋ค ํ์ง๊ณผ ์ฑ๋ฅ ๊ฐ์ ์ ์ง์คํ์ฌ, ์ญ๋ ๊ฐ์ฅ ์์ ์ ์ธ MAUI ๋ฆด๋ฆฌ์ค๋ก ํ๊ฐ๋ฐ๊ณ ์์ต๋๋ค. .NET ์ํฌ๋ก๋์ NuGet ํจํค์ง ๋ฐฉ์์ผ๋ก ๋ฐฐํฌ๋์ด ํ๋ก์ ํธ๋ณ ๋ฒ์ ๊ณ ์ (version pinning)์ด ๊ฐ๋ฅํฉ๋๋ค.
.NET MAUI 10 ํ๋ก์ ํธ ์ด๊ธฐ ์ค์
MAUI ์ฑ์ ๊ฐ์ฅ ๋น ๋ฅด๊ฒ ์คํํ๋ ๋ฐฉ๋ฒ์ .NET CLI๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๋๋ค. .NET 10์์๋ .NET Aspire ์๋น์ค ๊ธฐ๋ณธ๊ฐ์ด ํฌํจ๋ ์ ๋ฐ์ดํธ๋ ํ๋ก์ ํธ ํ ํ๋ฆฟ์ด ๋์ ๋์ด, ํ ๋ ๋ฉํธ๋ฆฌ์ ์๋น์ค ๋์ค์ปค๋ฒ๋ฆฌ๊ฐ ๊ธฐ๋ณธ์ ์ผ๋ก ์ฐ๊ฒฐ๋ฉ๋๋ค.
# Install the MAUI workload (if not already present)
dotnet workload install maui
# Create a new MAUI app
dotnet new maui -n CrossPlatformDemo
cd CrossPlatformDemo
# Run on Android emulator
dotnet build -t:Run -f net10.0-android๋จ์ผ ํ๋ก์ ํธ ๊ตฌ์กฐ๋ ํ๋ซํผ๋ณ ์ฝ๋๋ฅผ Platforms/ ํด๋ ์๋์ ํตํฉํ๊ณ ๋๋จธ์ง ์ฝ๋๋ฅผ ๊ณต์ ํ๋ ๋ฐฉ์์
๋๋ค. MauiProgram.cs ํ์ผ์ด ์ปดํฌ์ง์
๋ฃจํธ(composition root) ์ญํ ์ ํ๋ฉฐ, ์๋น์ค, ํฐํธ, ํธ๋ค๋ฌ ๋ฑ๋ก์ด ์ด๊ณณ์์ ์ด๋ฃจ์ด์ง๋๋ค.
using Microsoft.Extensions.Logging;
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
});
// Register services for dependency injection
builder.Services.AddSingleton<IApiService, ApiService>();
builder.Services.AddTransient<MainViewModel>();
#if DEBUG
builder.Logging.AddDebug();
#endif
return builder.Build();
}
}MAUI์ ์์กด์ฑ ์ฃผ์ ์ ASP.NET Core์ ๋์ผํ ํจํด์ ๋ฐ๋ฆ ๋๋ค. Singleton ์๋น์ค๋ ์ฑ ์ ์ฒด ์๋ช ๋์ ์ ์ง๋๊ณ , Transient ์๋น์ค๋ ์์ฒญ๋ง๋ค ์๋ก ์์ฑ๋ฉ๋๋ค. Scoped ์๋น์ค๋ ์ฌ์ฉ ๊ฐ๋ฅํ์ง๋ง, MAUI์๋ HTTP ์์ฒญ์ฒ๋ผ ๋ด์ฅ๋ ์ค์ฝํ ๊ฐ๋ ์ด ์์ผ๋ฏ๋ก ์ฃผ์๊ฐ ํ์ํฉ๋๋ค.
ํธ๋ค๋ฌ ์ํคํ ์ฒ: ํฌ๋ก์ค ํ๋ซํผ ๋ ๋๋ง์ ํต์ฌ ๊ตฌ์กฐ
MAUI๋ Xamarin.Forms์ ๋ ๋๋ฌ(Renderer)๋ฅผ ํธ๋ค๋ฌ(Handler) ์ํคํ ์ฒ๋ก ๋์ฒดํ์ต๋๋ค. ํธ๋ค๋ฌ๋ ๊ฐ ํฌ๋ก์ค ํ๋ซํผ ์ปจํธ๋กค์ ์์ ์ถ์ํ ๊ณ์ธต์ ํตํด ๋ค์ดํฐ๋ธ ๋์ ์ปจํธ๋กค์ ๋งคํํฉ๋๋ค. ํต์ฌ์ ์ธ ์ฐจ์ด์ ์ ํธ๋ค๋ฌ๊ฐ ์ํ๋ฅผ ๊ฐ์ง ์์ผ๋ฉฐ(stateless) ๊ฐ์ ๋ทฐ(virtual view)์ ๋ถ๋ฆฌ๋์ด ์๋ค๋ ์ ์ผ๋ก, ์ด๋ก ์ธํด ์ปค์คํฐ๋ง์ด์ง์ด ๋ ๋น ๋ฅด๊ณ ์ฉ์ดํฉ๋๋ค.
using Microsoft.Maui.Handlers;
public class CustomEntryHandler : EntryHandler
{
protected override void ConnectHandler(MauiAppCompatEditText platformView)
{
base.ConnectHandler(platformView);
// Remove the default underline on Android
platformView.SetBackgroundColor(Android.Graphics.Color.Transparent);
}
}
// Register in MauiProgram.cs
builder.ConfigureMauiHandlers(handlers =>
{
handlers.AddHandler<Entry, CustomEntryHandler>();
});.NET 10์์๋ Android์ Entry ๋ฐ Editor ์ปจํธ๋กค์ด AppCompatEditText์์ MauiAppCompatEditText๋ก ์ ํ๋์ด, SelectionChanged ์ด๋ฒคํธ์ ๋ํ ๋ค์ดํฐ๋ธ ์ง์์ด ์ถ๊ฐ๋์์ต๋๋ค. .NET 9์์ ๋์
๋ ๊ฐ์ ๋ CollectionView์ CarouselView ํธ๋ค๋ฌ๋ ์ด์ iOS ๋ฐ Mac Catalyst์์ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ ์ฉ๋์ด, ์ค๋ซ๋์ ์ง์ ๋๋ ์์ ์ฑ ๋ฌธ์ ๊ฐ ํด๊ฒฐ๋์์ต๋๋ค.
CommunityToolkit.Mvvm์ ํ์ฉํ MVVM ํจํด: ๋ณด์ผ๋ฌํ๋ ์ดํธ ์ ๊ฑฐ
CommunityToolkit.Mvvm ์์ค ์ ๋๋ ์ดํฐ๋ฅผ ์ฌ์ฉํ๋ฉด MVVM ํจํด ๊ตฌํ์ ํ์ํ ๋ฐ๋ณต ์ฝ๋๋ฅผ ์ฝ 80% ์์ค์ผ๋ก ์ค์ผ ์ ์์ต๋๋ค. ์๋์ผ๋ก INotifyPropertyChanged๋ฅผ ๊ตฌํํ๊ฑฐ๋ ์ปค๋งจ๋ ๋ํผ๋ฅผ ์์ฑํ ํ์ ์์ด, ์ดํธ๋ฆฌ๋ทฐํธ๋ง์ผ๋ก ์ฝ๋๊ฐ ์๋ ์์ฑ๋ฉ๋๋ค.
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
public partial class MainViewModel : ObservableObject
{
private readonly IApiService _apiService;
public MainViewModel(IApiService apiService)
{
_apiService = apiService;
}
// Source generator creates the 'Title' property with change notification
[ObservableProperty]
private string _title = string.Empty;
// Source generator creates the 'IsLoading' property
[ObservableProperty]
private bool _isLoading;
// Source generator creates an async ICommand
[RelayCommand]
private async Task LoadDataAsync()
{
IsLoading = true;
try
{
Title = await _apiService.FetchTitleAsync();
}
finally
{
IsLoading = false;
}
}
}XAML์์๋ ์์ฑ๋ ํ๋กํผํฐ์ ์ปค๋งจ๋์ ์ง์ ๋ฐ์ธ๋ฉํฉ๋๋ค.
<!-- MainPage.xaml -->
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:vm="clr-namespace:CrossPlatformDemo.ViewModels"
x:DataType="vm:MainViewModel">
<VerticalStackLayout Padding="20" Spacing="16">
<Label Text="{Binding Title}"
FontSize="24"
HorizontalOptions="Center" />
<Button Text="Load Data"
Command="{Binding LoadDataCommand}"
IsEnabled="{Binding IsLoading, Converter={StaticResource InverseBoolConverter}}" />
<ActivityIndicator IsRunning="{Binding IsLoading}"
IsVisible="{Binding IsLoading}" />
</VerticalStackLayout>
</ContentPage>x:DataType ์ดํธ๋ฆฌ๋ทฐํธ๋ ์ปดํ์ผ๋ ๋ฐ์ธ๋ฉ(compiled binding)์ ํ์ฑํํฉ๋๋ค. ๋ฆฌํ๋ ์
๊ธฐ๋ฐ ๋ฐ์ธ๋ฉ๋ณด๋ค ๋น ๋ฅด๋ฉฐ, ๋ฐ์ธ๋ฉ ๊ฒฝ๋ก์ ์ค๋ฅ๊ฐ ์์ ๊ฒฝ์ฐ ์ปดํ์ผ ์์ ์ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ฌ ๋ฐํ์ ๋ฌธ์ ๋ฅผ ์ฌ์ ์ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
.NET ๋ฉด์ ์ค๋น๊ฐ ๋์ จ๋์?
์ธํฐ๋ํฐ๋ธ ์๋ฎฌ๋ ์ดํฐ, flashcards, ๊ธฐ์ ํ ์คํธ๋ก ์ฐ์ตํ์ธ์.
.NET 10์ HybridWebView: ๋ค์ดํฐ๋ธ์ ์น์ ์ฐ๊ฒฐ
HybridWebView๋ MAUI ์ฑ ๋ด๋ถ์ ์น ์ฝํ ์ธ ๋ฅผ ์ฝ์ ํ๋ฉด์ C#๊ณผ JavaScript ๊ฐ ์๋ฐฉํฅ ํต์ ์ ์ ์งํ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค. .NET 10์์๋ ์ธ ๊ฐ์ง ๊ธฐ๋ฅ์ด ์ถ๊ฐ๋์์ต๋๋ค. Fire-and-forget ๋ฐฉ์์ JavaScript ํธ์ถ, ํ๋ซํผ๋ณ ์ค์ ์ ์ํ ์ด๊ธฐํ ์ด๋ฒคํธ, ๊ทธ๋ฆฌ๊ณ ์น ์์ฒญ ์ธํฐ์ ์ ์ ๋๋ค.
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
// Initialization event for platform-specific tweaks
hybridWebView.WebViewInitialized += (sender, args) =>
{
// Access the native platform view after initialization
System.Diagnostics.Debug.WriteLine("WebView ready");
};
}
// Call JavaScript from C#
private async void OnCallJsClicked(object sender, EventArgs e)
{
var result = await hybridWebView.InvokeJavaScriptAsync<string>(
"getFormData", // JS function name
HybridSampleContext.Default.String // JSON serialization context
);
await DisplayAlert("Result", result, "OK");
}
// Fire-and-forget: no return type needed (.NET 10)
private async void OnResetClicked(object sender, EventArgs e)
{
await hybridWebView.InvokeJavaScriptAsync("resetForm");
}
}JavaScript ์ธก์์๋ C#์ ํธ์ถ์ ์์ ํ๊ณ , ๋ฐ๋๋ก C# ์ธก์ผ๋ก ๋ฉ์์ง๋ฅผ ์ ์กํ ์ ์์ต๋๋ค.
function getFormData() {
return JSON.stringify({
name: document.getElementById('name').value,
email: document.getElementById('email').value
});
}
function resetForm() {
document.getElementById('name').value = '';
document.getElementById('email').value = '';
}InvokeJavaScriptAsync ์คํ ์ค JavaScript์์ ๋ฐ์ํ ์์ธ๋ ์ด์ .NET ์ธก์ผ๋ก ์๋ ์ ๋ฌ๋์ด ์์ธ๋ก ์ฒ๋ฆฌ๋ฉ๋๋ค. ์ด์ ๋ฒ์ ์์ ๋ฌธ์ ๊ฐ ๋๋ ์ฌ์ผ๋ฐํธ ์คํจ(silent failure)๊ฐ ์์ ํ ํด์๋์์ต๋๋ค.
SafeAreaEdges: ๋ชจ๋ ๋๋ฐ์ด์ค์์ ์ ๋ฐํ ๋ ์ด์์ ๊ตฌํ
.NET MAUI 10์ Layout, ContentView, ContentPage, Border, ScrollView์ SafeAreaEdges ์์ฑ์ ๋์
ํ์ต๋๋ค. None, SoftInput, Container, Default, All ๊ฐ์ ์ ๊ณตํ๋ ์๋ก์ด ์ด๊ฑฐํ(enum)์ ๊ธฐ์กด iOS ์ ์ฉ์ด๋ Page.UseSafeArea๋ฅผ ํฌ๋ก์ค ํ๋ซํผ ๋ฐฉ์์ผ๋ก ๋์ฒดํฉ๋๋ค.
<!-- Granular safe area control per section -->
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
SafeAreaEdges="All">
<Grid RowDefinitions="Auto,*,Auto">
<!-- Header respects all safe areas -->
<Border Grid.Row="0" SafeAreaEdges="Container">
<Label Text="Header" />
</Border>
<!-- Content scrolls under safe areas -->
<ScrollView Grid.Row="1" SafeAreaEdges="SoftInput">
<VerticalStackLayout Padding="16">
<Entry Placeholder="Type here..." />
</VerticalStackLayout>
</ScrollView>
<!-- Footer avoids home indicator -->
<Border Grid.Row="2" SafeAreaEdges="Container">
<Label Text="Footer" />
</Border>
</Grid>
</ContentPage>SoftInput์ ์ํํธ ํค๋ณด๋๊ฐ ๋ํ๋ ๋ ์ฝํ
์ธ ๋ฅผ ์๋์ผ๋ก ์กฐ์ ํฉ๋๋ค. Container๋ ๋
ธ์น, ์ผ์ ํ์ฐ์ง, ํ ์ธ๋์ผ์ดํฐ ์์ญ์ ํผํฉ๋๋ค. ์ปจํธ๋กค๋ณ๋ก ์ด ๊ฐ๋ค์ ์กฐํฉํ ์ ์์ด, ํค๋๋ ์ํ ๋ฐ ์๋์ ์์น์ํค๋ฉด์ ์ฝํ
์ธ ์์ญ์ ์์ ํ๊ฒ ์ ์งํ๋ ์ธ๋ฐํ ๋ ์ด์์ ์ ์ด๊ฐ ๊ฐ๋ฅํฉ๋๋ค.
Xamarin.Forms์์ .NET MAUI๋ก์ ๋ง์ด๊ทธ๋ ์ด์
Xamarin.Forms๋ 2024๋ 5์์ ๊ณต์ ์ง์์ด ์ข ๋ฃ๋์์ต๋๋ค. MAUI๋ก์ ๋ง์ด๊ทธ๋ ์ด์ ์ ๋จ์ํ ๋ค์์คํ์ด์ค ๋ณ๊ฒฝ์ ๋์ด ๊ตฌ์กฐ์ ์ธ ์์ ์ด ํ์ํฉ๋๋ค. ์ค์ ํ๋ก์ ํธ ์ ํ ๊ฒฝํ์ ๋ฐํ์ผ๋ก ์ ๋ฆฌํ ๋ง์ด๊ทธ๋ ์ด์ ์ฒดํฌ๋ฆฌ์คํธ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
Xamarin.Forms๋ 2024๋ 5์๋ถํฐ ์ง์์ด ์ค๋จ๋์์ต๋๋ค. Xamarin ๊ธฐ๋ฐ์ผ๋ก ์ด์ ์ค์ธ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ณด์ ๋ฐ ํธํ์ฑ ์ํ์ ์๊ณ ์์ต๋๋ค. .NET MAUI 10(LTS, 2028๋ 11์๊น์ง ์ง์)์ด ๊ณต์ ๋ง์ด๊ทธ๋ ์ด์ ๋์์ ๋๋ค.
- ํ๋ก์ ํธ ๊ตฌ์กฐ -- ํ๋ซํผ๋ณ ๊ฐ๋ณ ํ๋ก์ ํธ๋ฅผ MAUI ๋จ์ผ ํ๋ก์ ํธ ๋ชจ๋ธ๋ก ์ ํํฉ๋๋ค. ๊ณต์ ์ฝ๋๋ ๋ฃจํธ๋ก ์ด๋ํ๊ณ , ํ๋ซํผ ์ฝ๋๋
Platforms/ํ์์ ๋ฐฐ์นํฉ๋๋ค. - ๋ค์์คํ์ด์ค --
Xamarin.Forms๋ฅผMicrosoft.Maui.Controls๋ก,Xamarin.Essentials๋ฅผMicrosoft.Maui.Essentials(MAUI์ ๋ด์ฅ)๋ก ๊ต์ฒดํฉ๋๋ค. - ๋ ๋๋ฌ์์ ํธ๋ค๋ฌ๋ก -- ์ปค์คํ ๋ ๋๋ฌ๋ ํธ๋ค๋ฌ๋ก ์ฌ์์ฑํด์ผ ํฉ๋๋ค. ํธ๋ค๋ฌ API๊ฐ ๋ ๋จ์ํ์ง๋ง ๋งคํ ๋ก์ง์ ์์ดํฉ๋๋ค.
- ์์ ์ฝ๋ --
App.xaml.cs๊ธฐ๋ฐ ์ด๊ธฐํ๋ฅผ ๋น๋ ํจํด์ ์ฌ์ฉํ๋MauiProgram.cs๋ก ์ ํํฉ๋๋ค. - NuGet ํจํค์ง -- Xamarin ์๋์ ํจํค์ง ์ค ์๋น์์ MAUI ๋์ ํจํค์ง๊ฐ ์กด์ฌํฉ๋๋ค. ์ ๊ทธ๋ ์ด๋ ์ ํธํ์ฑ์ ๋ฐ๋์ ํ์ธํด์ผ ํฉ๋๋ค.
- ์์กด์ฑ ์ฃผ์
-- MAUI๋
Microsoft.Extensions.DependencyInjection์ ๋ค์ดํฐ๋ธ๋ก ์ฌ์ฉํฉ๋๋ค. ์๋ํํฐ DI ์ปจํ ์ด๋๋DependencyServiceํธ์ถ์ ๋ชจ๋ ๊ต์ฒด๊ฐ ํ์ํฉ๋๋ค.
.NET Upgrade Assistant๊ฐ 1-2๋ฒ ๋จ๊ณ๋ฅผ ๋ถ๋ถ์ ์ผ๋ก ์๋ํํด ์ฃผ์ง๋ง, ํธ๋ค๋ฌ ์ ํ(3๋ฒ)๊ณผ ๋น์ฆ๋์ค ๋ก์ง ์กฐ์ ์ ์์์ ์ด ๋ถ๊ฐํผํฉ๋๋ค.
2026๋ .NET MAUI ํต์ฌ ๋ฉด์ ์ง๋ฌธ
๋ค์์ .NET 10 ์ํ๊ณ๋ฅผ ๊ธฐ์ค์ผ๋ก 2026๋ ์ฑ์ฉ ๋ฉด์ ์์ ์ค์ ๋ก ์ถ์ ๋๋ ์ง๋ฌธ์ ๋๋ค.
MAUI ํธ๋ค๋ฌ ์ํคํ ์ฒ๋ Xamarin.Forms ๋ ๋๋ฌ์ ์ด๋ป๊ฒ ๋ค๋ฆ ๋๊น?
Xamarin.Forms์ ๋ ๋๋ฌ๋ ํฌ๋ก์ค ํ๋ซํผ ์ปจํธ๋กค๊ณผ ๋ค์ดํฐ๋ธ ๋ทฐ ์์ชฝ์ ๊ฐํ๊ฒ ๊ฒฐํฉ๋ ์๋ฐฉํฅ ์์กด์ฑ์ ๊ฐ์ง๊ณ ์์์ต๋๋ค. ๋ฐ๋ฉด MAUI์ ํธ๋ค๋ฌ๋ ์ํ๋ฅผ ๊ฐ์ง ์๋(stateless) ๋งคํผ์
๋๋ค. ํ๋กํผํฐ ๋ณ๊ฒฝ ์๋ฆผ์ ์์ ํ๊ณ ๋งคํผ ๋์
๋๋ฆฌ๋ฅผ ํตํด ๋ค์ดํฐ๋ธ ๋ทฐ์ ์ ์ฉํ๋ ๋ฐฉ์์
๋๋ค. ์ด๋ฌํ ๋ถ๋ฆฌ๋ก ์ธํด ํธ๋ค๋ฌ๋ ํ
์คํธ, ํ์ฅ, ์ฌ์ฌ์ฉ์ด ์ฉ์ดํฉ๋๋ค. PropertyMapper์ CommandMapper ๋์
๋๋ฆฌ๊ฐ ๊ธฐ์กด์ OnElementPropertyChanged ์ค๋ฒ๋ผ์ด๋ ํจํด์ ๋์ฒดํ๋ฉฐ, switch ๋ฌธ ๋ด๋ถ์ ๋ฌปํ ์๋ ์ปค์คํฐ๋ง์ด์ง ๋ก์ง์ด ๋ช
์์ ์ธ ํํ๋ก ์ ํ๋์์ต๋๋ค.
MAUI์์ DI ์๋ช ์ฃผ๊ธฐ์ ๊ด๋ จ๋ ํจ์ ์ ๋ฌด์์ ๋๊น?
MAUI๋ Singleton, Transient, Scoped ์๋ช ์ฃผ๊ธฐ๋ฅผ ๋ชจ๋ ์ง์ํ์ง๋ง, Scoped๋ ASP.NET Core์ ๋ค๋ฅด๊ฒ ๋์ํฉ๋๋ค. HTTP ์์ฒญ ๊ฐ์ ์์ฐ์ค๋ฌ์ด ์ค์ฝํ ๊ฒฝ๊ณ๊ฐ ์กด์ฌํ์ง ์๊ธฐ ๋๋ฌธ์ ๋๋ค. MAUI์์ ๋ฑ๋ก๋ Scoped ์๋น์ค๋ ์ปค์คํ ์ค์ฝํ๋ฅผ ์๋์ผ๋ก ์์ฑํ์ง ์๋ ํ Singleton์ฒ๋ผ ๋์ํฉ๋๋ค. ํํ ๋ฐ์ํ๋ ์ค์๋ก๋, ํ์ด์ง๋ณ ์ํ๋ฅผ ๋ณด์ ํ๋ ViewModel์ Singleton์ผ๋ก ๋ฑ๋กํ์ฌ ๋ค๋น๊ฒ์ด์ ๊ฐ ๋ฐ์ดํฐ๊ฐ ์์กดํ๋ ๊ฒฝ์ฐ, ๋๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ์ Transient๋ก ๋ฑ๋กํ์ฌ ์ปค๋ฅ์ ํ์ด ๊ณ ๊ฐ๋๋ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค. ์ผ๋ฐ์ ์ธ ์์น์ผ๋ก, ViewModel์ Transient, ์๋น์ค๋ Singleton์ผ๋ก ๋ฑ๋กํ๊ณ , Scoped๋ ์ค์ฝํ ์๋ช ์ฃผ๊ธฐ๋ฅผ ๋ช ์์ ์ผ๋ก ๊ด๋ฆฌํ์ง ์๋ ํ ์ฌ์ฉํ์ง ์๋ ๊ฒ์ด ๊ถ์ฅ๋ฉ๋๋ค.
DI ๊ด๋ จ ์ง๋ฌธ์ ๋ต๋ณํ ๋๋ MAUI์ ์๋ช ์ฃผ๊ธฐ๊ฐ ASP.NET Core์ ์์ฒญ ๊ธฐ๋ฐ ์ค์ฝํ ๋ชจ๋ธ๊ณผ ์ด๋ป๊ฒ ๋ค๋ฅธ์ง๋ฅผ ์ค๋ช ํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. ๋ฉด์ ๊ด์ ์ฅ์๊ฐ ์คํ๋๋ ๋ชจ๋ฐ์ผ ์ฑ์์ ๋ฐ์ํ๋ ๋ฉ๋ชจ๋ฆฌ ๋์์ ์ํ ๋ถ์ผ์น ๋ฌธ์ ์ ๋ํ ์ธ์ ์์ค์ ์ฃผ๋ก ํ๊ฐํฉ๋๋ค.
์ปดํ์ผ๋ ๋ฐ์ธ๋ฉ(Compiled Binding)๊ณผ ๋ฆฌํ๋ ์ ๊ธฐ๋ฐ ๋ฐ์ธ๋ฉ์ ์ฐจ์ด์ ์ ๋ฌด์์ ๋๊น?
๋ฆฌํ๋ ์
๊ธฐ๋ฐ ๋ฐ์ธ๋ฉ์ ๋ฐํ์์ System.Reflection์ ์ฌ์ฉํ์ฌ ํ๋กํผํฐ ๊ฒฝ๋ก๋ฅผ ํด์ํ๋ฏ๋ก, ์๋๊ฐ ๋๋ฆฌ๊ณ ์คํ๋ก ์ธํ ์ค๋ฅ๊ฐ ๋ฐํ์์์๋ง ๋ฐ๊ฒฌ๋ฉ๋๋ค. x:DataType๋ฅผ ์ฌ์ฉํ์ฌ ํ์ฑํํ๋ ์ปดํ์ผ๋ ๋ฐ์ธ๋ฉ์ ๋ฐ์ธ๋ฉ ๊ฒฝ๋ก๋ฅผ ์ปดํ์ผ ์์ ์ ํด์ํฉ๋๋ค. ์ปดํ์ผ๋ฌ๊ฐ ๋ฆฌํ๋ ์
์ ๊ฑด๋๋ฐ๋ ์ง์ ํ๋กํผํฐ ์ ๊ทผ ์ฝ๋๋ฅผ ์์ฑํ์ฌ, ์์ ์๊ฐ ๋จ์ถ, ๋ฉ๋ชจ๋ฆฌ ํ ๋น ๊ฐ์, ๋น๋ ์์ ๋ฐ์ธ๋ฉ ์ค๋ฅ ๊ฐ์ง๊ฐ ๊ฐ๋ฅํด์ง๋๋ค. .NET 10์์๋ ์๋ก์ด XAML ์์ค ์ ๋๋ ์ดํฐ๊ฐ XAML์ ๋ฐํ์ ํ์ฑ ๋์ ๋น๋ ์์ ์ ์ปดํ์ผํ์ฌ ์ด ์ต์ ํ๋ฅผ ๋์ฑ ๊ฐํํ์ต๋๋ค.
MAUI ์ฑ๊ณผ ASP.NET Core ๋ฐฑ์๋ ๊ฐ ์ฝ๋ ๊ณต์ ์ ๋ต์ ๋ฌด์์ ๋๊น?
๊ถ์ฅ๋๋ ์ ๊ทผ ๋ฐฉ์์ DTO, ์ ํจ์ฑ ๊ฒ์ฆ ๋ก์ง, ๋น์ฆ๋์ค ๊ท์น์ ํฌํจํ๋ ๊ณต์ ํด๋์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์
๋๋ค. MAUI ์ฑ๊ณผ ASP.NET Core ๋ฐฑ์๋๊ฐ ๋ชจ๋ ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฐธ์กฐํฉ๋๋ค. .NET 10์ MAUI์ฉ .NET Aspire ํตํฉ์ ํตํด ์ด ํจํด์ ๋์ฑ ๊ฐํํ๋ฉฐ, ๋ชจ๋ฐ์ผ๊ณผ ๋ฐฑ์๋ ํ๋ก์ ํธ ๊ฐ ์๋น์ค ๋์ค์ปค๋ฒ๋ฆฌ์ ํ
๋ ๋ฉํธ๋ฆฌ๋ฅผ ์ ๊ณตํฉ๋๋ค. System.Text.Json ์์ค ์ ๋๋ ์ดํฐ๋ฅผ ํ์ฉํ ๊ณต์ ๊ณ์ฝ(contract)์ผ๋ก ์ง๋ ฌํ ์ผ๊ด์ฑ์ ๋ณด์ฅํ ์ ์์ต๋๋ค. ํต์ฌ ์ ์ฝ ์ฌํญ์ ๊ณต์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ํ๋ซํผ๋ณ TFM์ด ์๋ net10.0์ ํ๊ฒ์ผ๋ก ํด์ผ ์ด์์ฑ์ด ์ ์ง๋๋ค๋ ์ ์
๋๋ค.
HybridWebView์ BlazorWebView๋ ์ด๋ค ์ฐจ์ด๊ฐ ์์ต๋๊น?
BlazorWebView๋ MAUI ์ฑ ๋ด๋ถ์์ ์์ ํ Blazor ์ ํ๋ฆฌ์ผ์ด์ ์ ํธ์คํ ํฉ๋๋ค. Razor ์ปดํฌ๋ํธ๊ฐ ๋ด์ฅ WebView์ ๋ ๋๋ง๋์ง๋ง, .NET ๋ฐํ์์ WebAssembly๊ฐ ์๋ ๋ค์ดํฐ๋ธ๋ก ์คํ๋ฉ๋๋ค. HybridWebView๋ ์ด๋ณด๋ค ๊ฐ๋ฒผ์ด ๊ตฌ์ฑ์ผ๋ก, ์ ์ HTML/CSS/JS ์ฝํ ์ธ ๋ฅผ ๋ก๋ํ๊ณ Blazor ํ๋ ์์ํฌ ์ค๋ฒํค๋ ์์ด C#-JavaScript ๊ฐ ์ธํฐ๋กญ์ ์ ๊ณตํฉ๋๋ค. ์ ํ ๊ธฐ์ค์ ์ฌ์ฉ ์ฌ๋ก์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋๋ค. BlazorWebView๋ ๊ธฐ์กด Blazor ์ปดํฌ๋ํธ๋ฅผ ๋ณด์ ํ ํ์ด ์ฝ๋ ์ฌ์ฌ์ฉ์ ์ํ ๋ ์ ํฉํฉ๋๋ค. HybridWebView๋ ๋์๋ณด๋, ์ง๋, ์๋ํฐ ๊ฐ์ ๊ธฐ์กด ์น ์ฝํ ์ธ ๋ฅผ ์ ์ฒด ํ๋ ์์ํฌ ์์ด ๋ค์ดํฐ๋ธ์ ํตํฉํด์ผ ํ๋ ์๋๋ฆฌ์ค์ ์ ํฉํฉ๋๋ค.
SharpSkill .NET ๋ฉด์ ์ฐ์ต์์ ์ด๋ฌํ ๊ฐ๋ ์ ์ธํฐ๋ํฐ๋ธ ์ฐ์ต ๋ฌธ์ ๋ก ์ฌํ ํ์ตํ ์ ์์ต๋๋ค.
์ฐ์ต์ ์์ํ์ธ์!
๋ฉด์ ์๋ฎฌ๋ ์ดํฐ์ ๊ธฐ์ ํ ์คํธ๋ก ์ง์์ ํ ์คํธํ์ธ์.
๊ฒฐ๋ก
- .NET MAUI 10์ LTS ๋ฆด๋ฆฌ์ค(2028๋ 11์๊น์ง ์ง์)๋ก, ๊ธฐ๋ฅ ์ถ๊ฐ๋ณด๋ค ์์ ์ฑ๊ณผ ์ฑ๋ฅ์ ์ง์คํ์ฌ ํ๋ก๋์ ํฌ๋ก์ค ํ๋ซํผ ์ฑ์ ์ ๋ขฐํ ์ ์๋ ์ ํ์ง์ ๋๋ค
- ํธ๋ค๋ฌ ์ํคํ
์ฒ๋ Xamarin ๋ ๋๋ฌ๋ฅผ ์ํ๋ฅผ ๊ฐ์ง ์๋ ๋งคํผ๋ก ๋์ฒดํ์ฌ,
PropertyMapper์CommandMapper๋ฅผ ํตํ ํ ์คํธ ์ฉ์ด์ฑ๊ณผ ์ปค์คํฐ๋ง์ด์ง ํธ์์ฑ์ ์ ๊ณตํฉ๋๋ค - CommunityToolkit.Mvvm ์์ค ์ ๋๋ ์ดํฐ๋ MVVM ๋ณด์ผ๋ฌํ๋ ์ดํธ ์ฝ๋๋ฅผ ๋ํญ ์ ๊ฑฐํฉ๋๋ค.
[ObservableProperty]์[RelayCommand]์ดํธ๋ฆฌ๋ทฐํธ๊ฐ ์๋INotifyPropertyChanged๋ฐ ์ปค๋งจ๋ ๊ตฌํ์ ๋์ฒดํฉ๋๋ค - .NET 10์ HybridWebView๋ fire-and-forget JavaScript ํธ์ถ, ์ด๊ธฐํ ์ด๋ฒคํธ, ์์ฒญ ์ธํฐ์ ์ ์ ์ถ๊ฐํ์ฌ ๋ค์ดํฐ๋ธ-์น ํตํฉ์ ๊ฐํํ์ต๋๋ค
- SafeAreaEdges๋ ๋๋ฐ์ด์ค ๋
ธ์น, ํค๋ณด๋, ์์คํ
๋ฐ์ ๋ํ ์ธ๋ฐํ ํฌ๋ก์ค ํ๋ซํผ ์ ์ด๋ฅผ ์ ๊ณตํ๋ฉฐ, ๊ธฐ์กด iOS ์ ์ฉ์ด๋
UseSafeArea๋ฅผ ๋์ฒดํฉ๋๋ค - Xamarin.Forms ๋ง์ด๊ทธ๋ ์ด์ ์๋ ํธ๋ค๋ฌ ์ฌ์์ฑ๊ณผ ์์ ์ฝ๋ ๋ฆฌํฉํ ๋ง์ด ํ์ํ๋ฉฐ, .NET Upgrade Assistant๊ฐ ๋ค์์คํ์ด์ค ๋ณ๊ฒฝ์ ์ฒ๋ฆฌํ์ง๋ง ์ปค์คํ ๋ ๋๋ฌ์ ๋ํ ์์์ ์ ๋ถ๊ฐํผํฉ๋๋ค
- ๋ฉด์ ์ค๋น ์ ํธ๋ค๋ฌ ๋ ๋ ๋๋ฌ ์ํคํ ์ฒ, ์ฅ์๊ฐ ์คํ ์ฑ์์์ DI ์๋ช ์ฃผ๊ธฐ ํจ์ , ์ปดํ์ผ๋ ๋ฐ์ธ๋ฉ, HybridWebView์ BlazorWebView์ ํธ๋ ์ด๋์คํ์ ์ง์คํ๋ ๊ฒ์ด ํจ๊ณผ์ ์ ๋๋ค
์ฐ์ต์ ์์ํ์ธ์!
๋ฉด์ ์๋ฎฌ๋ ์ดํฐ์ ๊ธฐ์ ํ ์คํธ๋ก ์ง์์ ํ ์คํธํ์ธ์.
ํ๊ทธ
๊ณต์
๊ด๋ จ ๊ธฐ์ฌ

C# ๋ฐ .NET ๋ฉด์ ์ง๋ฌธ: 2026๋ ์๋ฒฝ ๊ฐ์ด๋
๊ฐ์ฅ ์์ฃผ ์ถ์ ๋๋ C# ๋ฐ .NET ๋ฉด์ ์ง๋ฌธ 17์ ์ ๋๋ค. LINQ, async/await, ์์กด์ฑ ์ฃผ์ , Entity Framework, ASP.NET Core ๋ฑ ์์ธํ ๋ต๋ณ๊ณผ ์ฝ๋ ์์ ๋ฅผ ๋ค๋ฃน๋๋ค.

ASP.NET Core ๋ฉด์ ์ง๋ฌธ 25์ : ๋ฏธ๋ค์จ์ด, DI, Minimal API ์๋ฒฝ ์ ๋ฆฌ
ASP.NET Core ๋ฉด์ ์์ ์์ฃผ ์ถ์ ๋๋ ๋ฏธ๋ค์จ์ด ํ์ดํ๋ผ์ธ, ์์กด์ฑ ์ฃผ์ ์๋ช ์ฃผ๊ธฐ, Minimal API์ ๊ดํ 25๊ฐ์ง ํต์ฌ ์ง๋ฌธ๊ณผ ์ค๋ฌด ์ฝ๋ ์์ ๋ฅผ ์ฒด๊ณ์ ์ผ๋ก ์ ๋ฆฌํฉ๋๋ค.

.NET 9 Blazor: Blazor United๋ฅผ ํ์ฉํ ํ์คํ ๊ฐ๋ฐ ๊ฐ์ด๋ 2026
.NET 9 Blazor United๋ ์ ์ SSR, Server, WebAssembly ๋ ๋๋ง ๋ชจ๋๋ฅผ ํ๋์ ํ์คํ ํ๋ ์์ํฌ๋ก ํตํฉํฉ๋๋ค. ๋ ๋๋ง ๋ชจ๋ ํ์ฉ๋ฒ, ์คํธ๋ฆฌ๋ฐ ๋ ๋๋ง, ์์ฑ์ ์ฃผ์ , ํ๋ก๋์ ํจํด์ ์ค์ต ์ค์ฌ์ผ๋ก ๋ค๋ฃจ๋ ํํ ๋ฆฌ์ผ์ ๋๋ค.