13. Singleton 주입

1. Singleton 주입 개요
더보기
✔️ 사용 목적
- Logger 같은 전역 서비스(Singleton)를 ViewModel에 안전하게 주입하여 사용합니다.
- MVVM에서 Logger.Instance를 직접 참조하지 않고, 인터페이스 기반으로 느슨한 결합을 유지합니다.
✔️ 소스코드
WPF_Singleton.zip
0.23MB
2. 예제1 - Window 1개
더보기





📁 Services 구현
WPF_Singleton04_01MVVM/ ├── Services/ │ ├── ILoggerService.cs │ └── Logger.cs ← Singleton 구현 //├── ViewModels/ //│ └── MainViewModel.cs //├── Views/ //│ └── MainWindow.xaml //│ └── MainWindow.xaml.cs //└── App.xaml.cs
✔️ ILoggerService 인터페이스 구현

public interface ILoggerService { void Log(string message); string GetLogs(); }
✔️ Logger 클래스 구현

public sealed class Logger : ILoggerService { private static Logger? _instance = null; private static readonly object _lock = new(); private readonly StringBuilder _logs = new(); private Logger() { Console.WriteLine("Logger Singleton 인스턴스 생성됨"); } public static Logger Instance { get { lock (_lock) { return _instance ??= new Logger(); } } } public void Log(string message) { _logs.AppendLine($"{DateTime.Now:HH:mm:ss} - {message}"); } public string GetLogs() { return _logs.ToString(); } }
📁 ViewModels 구현
WPF_Singleton04_01MVVM/ //├── Services/ //│ ├── ILoggerService.cs //│ └── Logger.cs ← Singleton 구현 ├── ViewModels/ │ └── MainViewModel.cs //├── Views/ //│ └── MainWindow.xaml //│ └── MainWindow.xaml.cs //└── App.xaml.cs
✔️ MainViewModel 구현

public partial class MainViewModel : ObservableObject { private readonly ILoggerService _logger; [ObservableProperty] private string logText; public MainViewModel(ILoggerService logger) { _logger = logger; _logger.Log("MainViewModel 생성됨"); LogText = _logger.GetLogs(); } [RelayCommand] private void WriteLog() { _logger.Log("버튼 클릭 로그 기록"); LogText = _logger.GetLogs(); } }
📁 View 구현
WPF_Singleton04_01MVVM/ //├── Services/ //│ ├── ILoggerService.cs //│ └── Logger.cs ← Singleton 구현 //├── ViewModels/ //│ └── MainViewModel.cs ├── Views/ │ └── MainWindow.xaml │ └── MainWindow.xaml.cs //└── App.xaml.cs
✔️ MainWindow XAML 구현

Title="Logger Singleton" Height="250" Width="400"> <StackPanel Margin="10"> <Button Content="로그 남기기" Command="{Binding WriteLogCommand}" Margin="0 10"/> <TextBox Text="{Binding LogText}" Height="150" AcceptsReturn="True" VerticalScrollBarVisibility="Auto"/> </StackPanel>
✔️ MainWindow 코드 비하인드 구현

// Logger.Instance 를 서비스 인터페이스로 주입 DataContext = new MainViewModel(Logger.Instance);
3. 예제2 - Window 2개
더보기




📁 Services 구현
WPF_Singleton04_02MVVM/ ├── Services/ │ ├── ILoggerService.cs │ └── Logger.cs ← Singleton 구현 //├── ViewModels/ //│ └── MainViewModel.cs //│ └── SubViewModel.cs //├── Views/ //│ └── MainWindow.xaml //│ └── MainWindow.xaml.cs //│ └── SubWindow.xaml //│ └── SubWindow.xaml.cs //└── App.xaml.cs
✔️ ILoggerService 인터페이스 구현
public interface ILoggerService { void Log(string message); string GetLogs(); }
✔️ Logger 클래스 구현
// Logger 클래스는 애플리케이션 전역에서 하나만 존재해야 하는 로깅 클래스입니다. // 여러 창(Window) 또는 ViewModel에서 공통적으로 사용할 수 있도록 Singleton 패턴으로 구성됩니다. public sealed class Logger : ILoggerService { private static Logger? _instance = null; private static readonly object _lock = new(); private readonly StringBuilder _logs = new(); private Logger() { Console.WriteLine("Logger 인스턴스가 생성되었습니다."); } public static Logger Instance { get { lock (_lock) { return _instance ??= new Logger(); } } } public void Log(string message) { _logs.AppendLine($"{DateTime.Now:HH:mm:ss} - {message}"); } public string GetLogs() { return _logs.ToString(); } }
📁 ViewModels 구현
WPF_Singleton04_02MVVM/ //├── Services/ //│ ├── ILoggerService.cs //│ └── Logger.cs ← Singleton 구현 ├── ViewModels/ │ └── MainViewModel.cs │ └── SubViewModel.cs //├── Views/ //│ └── MainWindow.xaml //│ └── MainWindow.xaml.cs //│ └── SubWindow.xaml //│ └── SubWindow.xaml.cs //└── App.xaml.cs
✔️ MainViewModel 구현

public partial class MainViewModel : ObservableObject { private readonly ILoggerService _logger; [ObservableProperty] private string logText; public MainViewModel(ILoggerService logger) { _logger = logger; _logger.Log("MainWindow 열림"); LogText = _logger.GetLogs(); } [RelayCommand] private void WriteLog() { _logger.Log("MainWindow에서 로그 기록"); LogText = _logger.GetLogs(); } [RelayCommand] private void OpenSubWindow() { var sub = new SubWindow(); sub.Show(); } }
✔️ SubViewModel 구현

public partial class SubViewModel : ObservableObject { private readonly ILoggerService _logger; [ObservableProperty] private string logText; public SubViewModel(ILoggerService logger) { _logger = logger; _logger.Log("SubWindow 열림"); LogText = _logger.GetLogs(); } [RelayCommand] private void WriteLog() { _logger.Log("SubWindow에서 로그 기록"); LogText = _logger.GetLogs(); } }
📁 View 구현
WPF_Singleton04_02MVVM/ //├── Services/ //│ ├── ILoggerService.cs //│ └── Logger.cs ← Singleton 구현 //├── ViewModels/ //│ └── MainViewModel.cs //│ └── SubViewModel.cs ├── Views/ │ └── MainWindow.xaml │ └── MainWindow.xaml.cs │ └── SubWindow.xaml │ └── SubWindow.xaml.cs //└── App.xaml.cs
✔️ MainWindow.xaml구현

Title="MainWindow" Height="300" Width="400"> <StackPanel Margin="10"> <Button Content="로그 남기기" Command="{Binding WriteLogCommand}" Margin="0 0 0 10"/> <Button Content="SubWindow 열기" Command="{Binding OpenSubWindowCommand}" Margin="0 0 0 10"/> <TextBox Text="{Binding LogText}" AcceptsReturn="True" Height="200"/> </StackPanel>
✔️ MainWindow 코드 비하인드 구현
public MainWindow() { InitializeComponent(); // Logger.Instance 를 서비스 인터페이스로 주입 DataContext = new MainViewModel(Logger.Instance); }
✔️ SubWindow 구현

✔️ SubWindow 코드 비하인드 구현
public SubWindow() { InitializeComponent(); // Logger.Instance 를 서비스 인터페이스로 주입 DataContext = new SubViewModel(Logger.Instance); }
댓글을 사용할 수 없습니다.