[C#/MAUI/.NET6] ServiceCollectionExtensions 클래스 : AddTransient 확장 메소드를 사용해 MVVM 패턴에서 의존성 주입 사용하기
C#/MAUI 2022. 7. 30. 00:48728x90
반응형
728x170
▶ VIEWMODEL/BaseViewModel.cs
using CommunityToolkit.Mvvm.ComponentModel;
namespace TestProject;
/// <summary>
/// 베이스 뷰 모델
/// </summary>
[INotifyPropertyChanged]
public abstract partial class BaseViewModel
{
}
300x250
▶ VIEWMODEL/MainPageViewModel.cs
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
namespace TestProject
{
/// <summary>
/// 메인 페이지 뷰 모델
/// </summary>
public partial class MainPageViewModel : BaseViewModel
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 입력 텍스트
/// </summary>
[ObservableProperty]
private string inputText = null;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - MainPageViewModel()
/// <summary>
/// 생성자
/// </summary>
public MainPageViewModel()
{
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Private
#region 초기화하기 - Reset()
/// <summary>
/// 초기화하기
/// </summary>
[RelayCommand]
private void Reset()
{
InputText = string.Empty;
}
#endregion
#region 상세 페이지로 이동하기 - MoveDetailPage()
/// <summary>
/// 상세 페이지로 이동하기
/// </summary>
[RelayCommand]
private async Task MoveDetailPage()
{
await Shell.Current.GoToAsync("//메인페이지/메인상세페이지");
}
#endregion
}
}
728x90
▶ VIEWMODEL/MainDetailPageViewMode.cs
using CommunityToolkit.Mvvm.Input;
namespace TestProject
{
/// <summary>
/// 메인 상세 페이지 뷰 모델
/// </summary>
public partial class MainDetailPageViewModel : BaseViewModel
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - MainDetailPageViewModel()
/// <summary>
/// 생성자
/// </summary>
public MainDetailPageViewModel()
{
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Private
#region 부모 페이지로 이동하기 - MoveParentPage()
/// <summary>
/// 부모 페이지로 이동하기
/// </summary>
[RelayCommand]
private async Task MoveParentPage()
{
await Shell.Current.GoToAsync("..");
}
#endregion
}
}
반응형
▶ VIEWMODEL/SecondPageViewModel.cs
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
namespace TestProject
{
/// <summary>
/// 두번째 페이지 뷰 모델
/// </summary>
public partial class SecondPageViewModel : BaseViewModel
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 입력 텍스트
/// </summary>
[ObservableProperty]
private string inputText = null;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - SecondPageViewModel()
/// <summary>
/// 생성자
/// </summary>
public SecondPageViewModel()
{
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Private
#region 초기화하기 - Reset()
/// <summary>
/// 초기화하기
/// </summary>
[RelayCommand]
private void Reset()
{
InputText = string.Empty;
}
#endregion
}
}
▶ VIEW/BasePage.cs
namespace TestProject;
/// <summary>
/// 베이스 페이지
/// </summary>
public abstract class BasePage : ContentPage
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Protected
#region 생성자 - BasePage(viewModel)
/// <summary>
/// 생성자
/// </summary>
/// <param name="viewModel">뷰 모델</param>
protected BasePage(object viewModel = null)
{
BindingContext = viewModel;
if(string.IsNullOrWhiteSpace(Title))
{
Title = GetType().Name;
}
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Protected
#region 페이지가 나타나는 경우 처리하기 - OnAppearing()
/// <summary>
/// 페이지가 나타나는 경우 처리하기
/// </summary>
protected override void OnAppearing()
{
base.OnAppearing();
// 추후 기능을 추가한다.
}
#endregion
#region 페이지가 사라지는 경우 처리하기 - OnDisappearing()
/// <summary>
/// 페이지가 사라지는 경우 처리하기
/// </summary>
protected override void OnDisappearing()
{
base.OnDisappearing();
// 추후 기능을 추가한다.
}
#endregion
}
/// <summary>
/// 베이스 페이지
/// </summary>
/// <typeparam name="TViewModel">뷰 모델 타입</typeparam>
public abstract class BasePage<TViewModel> : BasePage where TViewModel : BaseViewModel
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 바인딩 컨텍스트 - BindingContext
/// <summary>
/// 바인딩 컨텍스트
/// </summary>
public new TViewModel BindingContext => (TViewModel)base.BindingContext;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Protected
#region 생성자 - BasePage(viewModel)
/// <summary>
/// 생성자
/// </summary>
/// <param name="viewModel">뷰 모델</param>
protected BasePage(TViewModel viewModel) : base(viewModel)
{
}
#endregion
}
▶ VIEW/MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<local:BasePage x:Class="TestProject.MainPage"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:TestProject"
x:TypeArguments="local:MainPageViewModel"
Title="메인 페이지">
<VerticalStackLayout
HorizontalOptions="Center"
VerticalOptions="Center"
Spacing="10">
<Entry
HorizontalOptions="Center"
Placeholder="텍스트를 입력해 주시기 바랍니다."
FontSize="16"
Text="{Binding InputText}" />
<Button
HorizontalOptions="Center"
Text="초기화"
Command="{Binding ResetCommand}" />
<Button
HorizontalOptions="Center"
Text="상세 페이지 이동하기"
Command="{Binding MoveDetailPageCommand}" />
</VerticalStackLayout>
</local:BasePage>
▶ VIEW/MainPage.xaml.cs
namespace TestProject;
/// <summary>
/// 메인 페이지
/// </summary>
public partial class MainPage : BasePage<MainPageViewModel>
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - MainPage()
/// <summary>
/// 생성자
/// </summary>
public MainPage(MainPageViewModel viewModel) : base(viewModel)
{
InitializeComponent();
}
#endregion
}
▶ VIEW/MainDetailPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<local:BasePage x:Class="TestProject.MainDetailPage"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:TestProject"
x:TypeArguments="local:MainDetailPageViewModel"
Title="메인 상세 페이지">
<VerticalStackLayout
HorizontalOptions="Center"
VerticalOptions="Center"
Spacing="10">
<Label
HorizontalOptions="Center"
FontSize="24"
Text="메인 상세 페이지" />
<Button
HorizontalOptions="Center"
Text="부모 페이지로 이동하기"
Command="{Binding MoveParentPageCommand}" />
</VerticalStackLayout>
</local:BasePage>
▶ VIEW/MainDetailPage.xaml.cs
namespace TestProject;
/// <summary>
/// 메인 상세 페이지
/// </summary>
public partial class MainDetailPage : BasePage<MainDetailPageViewModel>
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - MainPage()
/// <summary>
/// 생성자
/// </summary>
public MainDetailPage(MainDetailPageViewModel viewModel) : base(viewModel)
{
InitializeComponent();
}
#endregion
}
▶ VIEW/SecondPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<local:BasePage x:Class="TestProject.SecondPage"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:TestProject"
x:TypeArguments="local:SecondPageViewModel"
Title="두번째 페이지">
<VerticalStackLayout
HorizontalOptions="Center"
VerticalOptions="Center"
Spacing="10">
<Entry
HorizontalOptions="Center"
Placeholder="텍스트를 입력해 주시기 바랍니다."
FontSize="16"
Text="{Binding InputText}" />
<Button
HorizontalOptions="Center"
Text="초기화"
Command="{Binding ResetCommand}" />
</VerticalStackLayout>
</local:BasePage>
▶ VIEW/SecondPage.xaml.cs
namespace TestProject;
/// <summary>
/// 두번째 페이지
/// </summary>
public partial class SecondPage : BasePage<SecondPageViewModel>
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - SecondPage()
/// <summary>
/// 생성자
/// </summary>
public SecondPage(SecondPageViewModel viewModel) : base(viewModel)
{
InitializeComponent();
}
#endregion
}
▶ AppShell.xaml
<?xml version="1.0" encoding="UTF-8" ?>
<Shell x:Class="TestProject.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:TestProject">
<FlyoutItem
Title="메인 페이지"
Route="메인페이지">
<ShellContent ContentTemplate="{DataTemplate local:MainPage}" />
</FlyoutItem>
<FlyoutItem
Title="두번째 페이지"
Route="두번째페이지">
<ShellContent ContentTemplate="{DataTemplate local:SecondPage}" />
</FlyoutItem>
</Shell>
▶ AppShell.xaml.cs
namespace TestProject;
/// <summary>
/// 앱 셸
/// </summary>
public partial class AppShell : Shell
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - AppShell()
/// <summary>
/// 생성자
/// </summary>
public AppShell()
{
InitializeComponent();
Routing.RegisterRoute("메인페이지/메인상세페이지", typeof(MainDetailPage));
}
#endregion
}
▶ MauiProgram.cs
using CommunityToolkit.Maui;
namespace TestProject;
/// <summary>
/// MAUI 프로그램
/// </summary>
public static class MauiProgram
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Public
#region MAUI 앱 생성하기 - CreateMauiApp()
/// <summary>
/// MAUI 앱 생성하기
/// </summary>
/// <returns>MAUI 앱</returns>
public static MauiApp CreateMauiApp()
{
MauiAppBuilder builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.UseMauiCommunityToolkit()
.ConfigureFonts
(
fontCollection =>
{
fontCollection.AddFont("OpenSans-Regular.ttf" , "OpenSansRegular" );
fontCollection.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
}
);
builder.Services.AddTransient<MainPage , MainPageViewModel >();
builder.Services.AddTransient<MainDetailPage, MainDetailPageViewModel>();
builder.Services.AddTransient<SecondPage , SecondPageViewModel >();
return builder.Build();
}
#endregion
}
728x90
반응형
그리드형(광고전용)
댓글을 달아 주세요