How to Use
Learn Dreamine through real sample projects. All samples live in the 998. DEMO/000. Sample folder of the repository and build & run as-is.
Getting Started
Add the Dreamine.MVVM.FullKit package to your WPF project and put a single [DreamineEntry] on your App class. The source generator emits everything else — DI container setup, automatic ViewModel registration, View/ViewModel mapping, and ViewManager registration.
using Dreamine.MVVM.Attributes;
using System.Windows;
namespace MyApp
{
[DreamineEntry] // 이 한 줄로 부트스트랩 완료 (bootstrap done with this single line)
public partial class App : Application
{
}
}SampleCore — WPF MVVM Basics
Dreamine splits a screen into three parts: Model (state), Event (logic), and ViewModel (binding). Fields marked [DreamineModel] and [DreamineEvent] are injected automatically, and [DreamineCommand] generates ICommand properties.
public partial class MainWindowViewModel : ViewModelBase
{
[DreamineModel] private MainWindowModel _model; // 상태 (state)
[DreamineEvent] private MainWindowEvent _event; // 로직 (logic)
public string Title => Model.Title;
public string Message => Model.Message;
[DreamineCommand] private void Ok() => Event.Ok(); // → OkCommand
[DreamineCommand] private void Cancel() => Event.Cancel(); // → CancelCommand
[DreamineCommand] private void SubPage() => Event.SubPage();
}
Actual logic such as navigation and window control lives in the Event class. Inject IViewManager via the constructor to show other views.
public class MainWindowEvent
{
private readonly IViewManager _viewManager;
public MainWindowEvent(IViewManager viewManager) => _viewManager = viewManager;
public void Ok() => MessageBox.Show("확인 클릭됨!");
public void SubPage() => _viewManager.Show<PageSubViewModel>(); // 화면 이동
}
998. DEMO/000. Sample/010. Wpfs/SampleCoreSampleSmart — Smart Pattern + Threading
A condensed pattern that delegates even the command body to the generator: declare a partial method with [DreamineCommand("Event.Ok")] and the forwarding code is generated. This sample also shows the colocation layout (MainWindow.xaml.ViewModel.cs next to the view) and background job registration with IDreamineThreadManager.
public partial class MainWindowViewModel : ViewModelBase
{
[DreamineModel] private MainWindowModel _model;
[DreamineEvent] private MainWindowEvent _event;
// 본문 없는 partial 선언 → Event.Ok()로 포워딩하는 코드가 자동 생성
[DreamineCommand("Event.Ok")] private partial void Ok();
[DreamineCommand("Event.SubPage")] private partial void SubPage();
public MainWindowViewModel(IDreamineLogger logger, IDreamineThreadManager threads)
{
threads.Register(
new DreamineThreadOptions { Name = "MonitoringJob", IntervalMs = 10, AutoStart = true },
async token => { /* 주기 실행 작업 (periodic work) */ });
}
}
998. DEMO/000. Sample/010. Wpfs/SampleSmartSampleEnterprise — Modular Architecture
As the app grows, split layers into separate projects: Models / Events / ViewModels / Views / Styles / Resources. The [DreamineEntry] bootstrap works unchanged. Use this layout when you need team-level ownership and enforced reference direction.
SampleEnterprise/ ← 진입점 ([DreamineEntry] App)
SampleEnterprise.Models/ ← 상태
SampleEnterprise.Events/ ← 로직
SampleEnterprise.ViewModels/ ← 바인딩
SampleEnterprise.Views/ ← XAML 화면
SampleEnterprise.Styles/ ← 공용 스타일
SampleEnterprise.Resources/ ← 리소스(문자열·이미지)
998. DEMO/000. Sample/010. Wpfs/Enterprise/SampleEnterpriseSample01 — WPF + Blazor Hybrid
Runs a Blazor Server inside a WPF app — this very site works the same way. Register AddDreamineHybridWpf() and AddDreamineBlazorServer<AppShell>() to run the WPF window and the web UI in one process, share state via IHybridStateStore, and exchange messages via IHybridMessageBus.
[STAThread]
public static void Main()
{
var builder = Host.CreateApplicationBuilder();
builder.Services.AddDreamineHybridWpf();
builder.Services.AddSingleton<MainWindow>();
// WPF ↔ Blazor 공유 상태
builder.Services.AddSingleton<IHybridStateStore<CounterState>>(
new HybridStateStore<CounterState>(new CounterState(0, "-", null)));
builder.Services.AddDreamineBlazorServer<AppShell>(options =>
{
options.Port = 5000;
options.SharedServiceTypes.Add(typeof(IHybridStateStore<CounterState>));
});
builder.Build().RunDreamineWpfApp<App>();
}
The Blazor-side ViewModel only publishes requests; execution and state ownership stay in the WPF shell.
public sealed class IndexViewModel
{
private readonly IHybridMessageBus _bus;
public IndexViewModel(IHybridMessageBus bus) => _bus = bus;
// Blazor는 요청만 발행 — 실행은 WPF 쉘이 담당
public Task OpenProjectAsync() =>
_bus.PublishAsync(new DashboardActionRequestedMessage(DashboardAction.OpenProject));
}
998. DEMO/000. Sample/040. Hybrids/Sample01SampleCrossUi — One ViewModel, Four UIs
Write a UI-independent ViewModel once in a Shared project and reuse it unmodified across WPF, WinForms, Blazor, and .NET MAUI. Logic lives in the Event class; the ViewModel exposes only [DreamineCommand] forwarders and read-only state.
// Shared 프로젝트에 한 번만 작성 — WPF·WinForms·Blazor·MAUI에서 그대로 사용
public partial class CounterViewModel : ViewModelBase
{
[DreamineEvent] private CounterEvent _event;
public int Count => Event.Count;
public ObservableCollection<CounterLogItem> Logs => Event.Logs;
[DreamineCommand("Event.Increment")] private partial void Increment();
[DreamineCommand("Event.Reset")] private partial void Reset();
}
998. DEMO/000. Sample/050. CrossUi