iconDreamine
← 지식 Q&A 목록
ViewModel · Published

DreamineProperty를 사용하면 일반 ViewModel 속성을 직접 작성하는 것과 무엇이 다른가요?

요청 판정 Supported 개정 1 / 1 조회 752초 동안 분석2026-07-20 23:30
직접 답변

`DreamineProperty`의 핵심 차이는 ViewModel 속성의 반복 코드를 직접 작성하지 않고, 필드에 특성을 붙여 컴파일 시 보조 프로퍼티를 생성한다는 점입니다. 예를 들어 `_message` 필드에 `[DreamineProperty]`를 적용하면 생성기가 명명 규칙에 따라 대응 프로퍼티를 만듭니다. 반면 일반 ViewModel 속성은 프로퍼티 선언과 필요한 동작을 개발자가 직접 구현해야 합니다.

핵심 코드 근거

직접 근거

ControlsViewModel 역할 설명 코드 선언

비즈니스 동작이 연결되지 않은 순수 UI 상태에는 DreamineProperty를 ViewModel에서 직접 사용한다고 설명합니다.

public partial class ControlsViewModel : ViewModelBase, IActivatable, IVisibilityAware
/// <summary>
/// \if KO
/// <para>Controls View Model 기능과 관련 상태를 캡슐화합니다.</para>
/// \endif
/// \if EN
/// <para>Controls showcase ViewModel. Platform-independent. Reusable across WPF, WinForms, Blazor, and MAUI. Actual behavior lives in <see cref="ControlsEvent"/>; pure UI-only state (no business logic attached) uses [DreamineProperty] directly here.</para>
/// \endif
/// </summary>
public partial class ControlsViewModel : ViewModelBase, IActivatable, IVisibilityAware
{
    // ── ViewSwitcher.NotifyShown/NotifyHidden 데모 ──────────
    /// <summary>
    /// \if KO
20_SOURCES/998. DEMO/000. Sample/050. CrossUi/SampleCrossUi.Shared/ViewModels/ControlsViewModel.cs:90-102
직접 근거

DreamineAutoWiringGenerator 선언 코드 선언

DreamineProperty 적용 필드를 기반으로 보조 프로퍼티 코드를 만드는 증분 생성기임을 명시합니다.

public sealed class DreamineAutoWiringGenerator : IIncrementalGenerator

namespace Dreamine.MVVM.Generators
{
    /// <summary>
    /// <c>DreamineModelAttribute</c>, <c>DreamineEventAttribute</c>,
    /// <c>DreaminePropertyAttribute</c>가 적용된 필드를 기반으로
    /// 보조 프로퍼티 코드를 생성하는 증분 생성기입니다.
    /// </summary>
    [Generator]
    public sealed class DreamineAutoWiringGenerator : IIncrementalGenerator
    {
        private const string ModelAttributeMetadataName = "Dreamine.MVVM.Attributes.DreamineModelAttribute";
        private const string EventAttributeMetadataName = "Dreamine.MVVM.Attributes.DreamineEventAttribute";
20_SOURCES/100. Library/Generators/DreamineAutoWiringGenerator.cs:9-21
직접 근거

DreaminePropertyAttribute 선언 코드 선언

특성이 필드 대상이며, PropertyName 생략 시 필드 이름에서 기본 프로퍼티 이름을 유도한다고 설명합니다.

public sealed class DreaminePropertyAttribute : Attribute
    /// When <see cref="PropertyName"/> is omitted, the default naming convention derives the property name from the field name.
    /// </para>
    /// \endif
    /// </remarks>
    [AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
    public sealed class DreaminePropertyAttribute : Attribute
    {
        /// <summary>
        /// \if KO
        /// 생성될 프로퍼티 이름을 가져옵니다.
        /// \endif
        /// \if EN
        /// Gets the name of the property to generate.
20_SOURCES/100. Library/Attributes/DreaminePropertyAttribute.cs:26-38
직접 근거

Generator README 코드 선언

DreamineProperty를 포함한 선언적 특성을 기반으로 MVVM 반복 코드를 컴파일 타임에 생성한다고 설명합니다.

This package generates MVVM boilerplate code at compile time based on declarative attributes.

This package generates MVVM boilerplate code at **compile time** based on declarative attributes.

The main attributes currently handled are:

- `DreamineProperty`
- `DreamineEntry`
- `DreamineModel`
- `DreamineEvent`
- `DreamineCommand`

The goal of this package is to reduce repetitive code while keeping generation rules and constraints explicit.
20_SOURCES/100. Library/Generators/README.md:13-25
직접 근거

PageSubViewModel의 DreamineProperty 사용 예 코드 선언

`_message` 필드에 `[DreamineProperty]`를 적용한 실제 ViewModel 예제입니다.

[DreamineProperty] private string _message = string.Empty;
        /// \endif
        /// \if EN
        /// <para>Stores the message value.</para>
        /// \endif
        /// </summary>
        [DreamineProperty]
        private string _message = string.Empty;

        /// <summary>
        /// \if KO
        /// <para>WindowSub 창이 열려 있는지 여부입니다.</para>
        /// \endif
        /// \if EN
20_SOURCES/998. DEMO/000. Sample/010. Wpfs/SampleSmart/Pages/PageSub/PageSub.xaml.ViewModel.cs:53-65

추가 설명

최소 구현 형태

```csharp [DreamineProperty] private string _message = string.Empty; ``` 실제 샘플은 `PageSubViewModel`에서 이 형태를 사용합니다. 특성은 필드에만 적용할 수 있고, `PropertyName`을 생략하면 필드 이름으로부터 생성될 프로퍼티 이름을 정합니다.

실제 차이

`DreamineProperty`는 런타임의 별도 속성 유형이 아니라 소스 생성기의 입력입니다. `DreamineAutoWiringGenerator`가 해당 특성이 적용된 필드를 찾아 보조 프로퍼티 코드를 생성하며, 생성은 컴파일 타임에 수행됩니다. 흐름: `[DreamineProperty]` 필드 선언 → 증분 소스 생성기 처리 → 대응 ViewModel 프로퍼티 생성 따라서 차이는 속성의 값 자체보다 작성·유지 방식에 있습니다. 직접 구현하면 프로퍼티 코드를 소스에 명시하고, `DreamineProperty`를 사용하면 필드와 생성 규칙만 선언합니다.

확인 가능한 범위

제공된 발췌에는 생성된 setter 본문이 포함되어 있지 않으므로, 변경 알림 호출 방식이나 값 비교 방식까지는 단정할 수 없습니다. 또한 구체적인 생성 이름은 기본 명명 규칙이 적용된다는 것까지만 확인되며, `_message`가 정확히 `Message`로 생성된다는 구현 규칙은 이 발췌만으로 완전히 입증되지 않습니다.

배치 기준

순수 UI 상태는 ViewModel의 필드에 `[DreamineProperty]`를 직접 적용하는 방식이 저장소 샘플의 의도입니다. 반면 버튼 클릭, 선택 변경, 토글처럼 실제 동작이 붙는 로직은 `Event` 클래스에 두고 ViewModel이 호출하도록 구성한 샘플이 확인됩니다. 즉 단순 상태는 ViewModel의 `DreamineProperty`, 실제 동작은 해당 기능의 `Event` 계층에 두는 것이 이 저장소의 예제 구조와 맞습니다.

확인되지 않은 내용

  • 생성된 setter가 어떤 변경 알림 메서드를 호출하는지는 제공된 발췌로 확인되지 않습니다.
  • 기본 명명 규칙이 `_message`를 정확히 `Message`로 변환하는지는 생성기 구현 발췌가 없어 확정할 수 없습니다.
기술 세부정보

정규화된 질문: DreamineProperty를 사용하면 일반 ViewModel 속성을 직접 작성하는 것과 무엇이 다른가요?

Source · PageSubViewModel의 DreamineProperty 사용 예 source-1 · 직접 근거 · confidence 1.00
Source · DreaminePropertyAttribute 선언 source-2 · 직접 근거 · confidence 1.00
Source · DreamineAutoWiringGenerator 선언 source-3 · 직접 근거 · confidence 1.00
Source · Generator README source-4 · 직접 근거 · confidence 1.00
Source · ControlsViewModel 역할 설명 source-5 · 직접 근거 · confidence 1.00
Source · ControlsEvent 역할 설명 source-6 · 직접 근거 · confidence 1.00
검색 원본
서버 저장소 소스 코드
생성 모델
codex-cli:default
생성 정책
dreamine-repository-search-v4
마지막 검증
2026-07-20 23:30:36
이 답변이 유용했나요?