Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@ This documentation covers using ReactiveUI Source Generators to simplify and enh
ReactiveUI Source Generators automatically generate ReactiveUI objects to streamline your code. These Source Generators are designed to work with ReactiveUI V19.5.31+ and support the following features:

- `[Reactive]` With field and access modifiers, partial property support (C# 13 Visual Studio Version 17.12.0), partial properties with initializer support (C# preview only)
- `[Reactive(SetModifier = AccessModifier.Protected)]` With field and access modifiers, (Not Required for partial properties, configure set accessor with the property decalaration).
- `[Reactive(SetModifier = AccessModifier.Protected)]` With field and access modifiers, (Not Required for partial properties, configure set accessor with the property declaration).
- `[Reactive(Inheritance = InheritanceModifier.Virtual)]` With field and access modifiers. This will generate a virtual property.
- `[Reactive(UseRequired = true)]` With field and access modifiers. This will generate a required property, (Not Required for partial properties, use required keyword for property decalaration).
- `[Reactive(UseRequired = true)]` With field and access modifiers. This will generate a required property, (Not Required for partial properties, use required keyword for property declaration).
- `[Reactive(nameof(RaiseProperty1), nameof(RaiseProperty2))]` With field and property changed notification for additional properties.
- `[ObservableAsProperty]` With field, method, Observable property and partial property support (C# 13 Visual Studio Version 17.12.0)
- `[ObservableAsProperty(ReadOnly = false)]` Removes readonly keyword from the generated helper field
- `[ObservableAsProperty(PropertyName = "ReadOnlyPropertyName")]`
Expand Down Expand Up @@ -91,6 +92,9 @@ Generates a derived list from a `ReadOnlyObservableCollection` backing field.
### `[ReactiveCollection]`
Generates property changed notifications on add, remove, and new actions on an `ObservableCollection` backing field.

### `[IReactiveObject]`
Generates `IReactiveObject` implementation for classes not able to inherit from `ReactiveObject`.

## Historical Approach

### Read-Write Properties
Expand Down Expand Up @@ -685,7 +689,7 @@ public partial class MyReactiveClass : ReactiveObject
}
```

### ReactiveObject implementation for classes not able to inherit from ReactiveObject
### IReactiveObject implementation for classes not able to inherit from ReactiveObject
```csharp
using ReactiveUI;
using ReactiveUI.SourceGenerators;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//HintName: ReactiveUI.SourceGenerators.AccessModifier.g.cs
// Copyright (c) 2025 .NET Foundation and Contributors. All rights reserved.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for full license information.

// <auto-generated/>
#pragma warning disable
#nullable enable
namespace ReactiveUI.SourceGenerators;

/// <summary>
/// AccessModifier.
/// </summary>
internal enum AccessModifier
{
Public,
Protected,
Internal,
Private,
InternalProtected,
PrivateProtected,
Init,
}

/// <summary>
/// Property Access Modifier.
/// </summary>
internal enum PropertyAccessModifier
{
Public,
Protected,
Internal,
Private,
InternalProtected,
PrivateProtected,
}

/// <summary>
/// InheritanceModifier.
/// </summary>
internal enum InheritanceModifier
{
None,
Virtual,
Override,
New,
}

internal enum SplatRegistrationType
{
None,
LazySingleton,
Constant,
PerRequest,
}
#nullable restore
#pragma warning restore
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//HintName: ReactiveUI.SourceGenerators.ReactiveAttribute.g.cs
// Copyright (c) 2025 .NET Foundation and Contributors. All rights reserved.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for full license information.

// <auto-generated/>
#pragma warning disable
#nullable enable
namespace ReactiveUI.SourceGenerators;

/// <summary>
/// ReactiveAttribute.
/// </summary>
/// <seealso cref="Attribute" />
[global::System.AttributeUsage(global::System.AttributeTargets.Field | global::System.AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
internal sealed class ReactiveAttribute : global::System.Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="ReactiveAttribute"/> class.
/// </summary>
public ReactiveAttribute(params string[] alsoNotify)
{
AlsoNotify = alsoNotify;
}

/// <summary>
/// Gets the AccessModifier of the set property.
/// </summary>
/// <value>
/// The AccessModifier of the set property.
/// </value>
public AccessModifier SetModifier { get; init; }

/// <summary>
/// Gets the InheritanceModifier of the property.
/// </summary>
public InheritanceModifier Inheritance { get; init; }

/// <summary>
/// Use Required attribute to indicate that the property is required.
/// </summary>
public bool UseRequired { get; init; }

/// <summary>
/// Gets the AlsoNotify properties to raise change notifications for.
/// </summary>
public string[]? AlsoNotify { get; }
}
#nullable restore
#pragma warning restore
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//HintName: TestNs.TestVM.Properties.g.cs
// <auto-generated/>
using ReactiveUI;

#pragma warning disable
#nullable enable

namespace TestNs
{

public partial class TestVM
{

/// <inheritdoc cref="_test4"/>
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
public int Test4
{
get => _test4;
[global::System.Diagnostics.CodeAnalysis.MemberNotNull("_test4")]
set
{
this.RaiseAndSetIfChanged(ref _test4, value);
}
}
}
}
#nullable restore
#pragma warning restore
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ namespace ReactiveUI.SourceGenerators;
[global::System.AttributeUsage(global::System.AttributeTargets.Field | global::System.AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
internal sealed class ReactiveAttribute : global::System.Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="ReactiveAttribute"/> class.
/// </summary>
public ReactiveAttribute(params string[] alsoNotify)
{
AlsoNotify = alsoNotify;
}

/// <summary>
/// Gets the AccessModifier of the set property.
/// </summary>
Expand All @@ -26,13 +34,18 @@ internal sealed class ReactiveAttribute : global::System.Attribute

/// <summary>
/// Gets the InheritanceModifier of the property.
/// </sumary>
/// </summary>
public InheritanceModifier Inheritance { get; init; }

/// <summary>
/// Use Required attribute to indicate that the property is required.
/// </summary>
public bool UseRequired { get; init; }

/// <summary>
/// Gets the AlsoNotify properties to raise change notifications for.
/// </summary>
public string[]? AlsoNotify { get; }
}
#nullable restore
#pragma warning restore
#pragma warning restore
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ namespace ReactiveUI.SourceGenerators;
[global::System.AttributeUsage(global::System.AttributeTargets.Field | global::System.AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
internal sealed class ReactiveAttribute : global::System.Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="ReactiveAttribute"/> class.
/// </summary>
public ReactiveAttribute(params string[] alsoNotify)
{
AlsoNotify = alsoNotify;
}

/// <summary>
/// Gets the AccessModifier of the set property.
/// </summary>
Expand All @@ -26,13 +34,18 @@ internal sealed class ReactiveAttribute : global::System.Attribute

/// <summary>
/// Gets the InheritanceModifier of the property.
/// </sumary>
/// </summary>
public InheritanceModifier Inheritance { get; init; }

/// <summary>
/// Use Required attribute to indicate that the property is required.
/// </summary>
public bool UseRequired { get; init; }

/// <summary>
/// Gets the AlsoNotify properties to raise change notifications for.
/// </summary>
public string[]? AlsoNotify { get; }
}
#nullable restore
#pragma warning restore
#pragma warning restore
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ public int Test3
{
get => _test3;
[global::System.Diagnostics.CodeAnalysis.MemberNotNull("_test3")]
set => this.RaiseAndSetIfChanged(ref _test3, value);
set
{
this.RaiseAndSetIfChanged(ref _test3, value);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ namespace ReactiveUI.SourceGenerators;
[global::System.AttributeUsage(global::System.AttributeTargets.Field | global::System.AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
internal sealed class ReactiveAttribute : global::System.Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="ReactiveAttribute"/> class.
/// </summary>
public ReactiveAttribute(params string[] alsoNotify)
{
AlsoNotify = alsoNotify;
}

/// <summary>
/// Gets the AccessModifier of the set property.
/// </summary>
Expand All @@ -26,13 +34,18 @@ internal sealed class ReactiveAttribute : global::System.Attribute

/// <summary>
/// Gets the InheritanceModifier of the property.
/// </sumary>
/// </summary>
public InheritanceModifier Inheritance { get; init; }

/// <summary>
/// Use Required attribute to indicate that the property is required.
/// </summary>
public bool UseRequired { get; init; }

/// <summary>
/// Gets the AlsoNotify properties to raise change notifications for.
/// </summary>
public string[]? AlsoNotify { get; }
}
#nullable restore
#pragma warning restore
#pragma warning restore
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ public int Test1
{
get => _test1;
[global::System.Diagnostics.CodeAnalysis.MemberNotNull("_test1")]
set => this.RaiseAndSetIfChanged(ref _test1, value);
set
{
this.RaiseAndSetIfChanged(ref _test1, value);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ namespace ReactiveUI.SourceGenerators;
[global::System.AttributeUsage(global::System.AttributeTargets.Field | global::System.AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
internal sealed class ReactiveAttribute : global::System.Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="ReactiveAttribute"/> class.
/// </summary>
public ReactiveAttribute(params string[] alsoNotify)
{
AlsoNotify = alsoNotify;
}

/// <summary>
/// Gets the AccessModifier of the set property.
/// </summary>
Expand All @@ -26,13 +34,18 @@ internal sealed class ReactiveAttribute : global::System.Attribute

/// <summary>
/// Gets the InheritanceModifier of the property.
/// </sumary>
/// </summary>
public InheritanceModifier Inheritance { get; init; }

/// <summary>
/// Use Required attribute to indicate that the property is required.
/// </summary>
public bool UseRequired { get; init; }

/// <summary>
/// Gets the AlsoNotify properties to raise change notifications for.
/// </summary>
public string[]? AlsoNotify { get; }
}
#nullable restore
#pragma warning restore
#pragma warning restore
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ public string Value
{
get => value;
[global::System.Diagnostics.CodeAnalysis.MemberNotNull("this.value")]
set => this.RaiseAndSetIfChanged(ref this.value, value);
set
{
this.RaiseAndSetIfChanged(ref this.value, value);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ namespace ReactiveUI.SourceGenerators;
[global::System.AttributeUsage(global::System.AttributeTargets.Field | global::System.AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
internal sealed class ReactiveAttribute : global::System.Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="ReactiveAttribute"/> class.
/// </summary>
public ReactiveAttribute(params string[] alsoNotify)
{
AlsoNotify = alsoNotify;
}

/// <summary>
/// Gets the AccessModifier of the set property.
/// </summary>
Expand All @@ -26,13 +34,18 @@ internal sealed class ReactiveAttribute : global::System.Attribute

/// <summary>
/// Gets the InheritanceModifier of the property.
/// </sumary>
/// </summary>
public InheritanceModifier Inheritance { get; init; }

/// <summary>
/// Use Required attribute to indicate that the property is required.
/// </summary>
public bool UseRequired { get; init; }

/// <summary>
/// Gets the AlsoNotify properties to raise change notifications for.
/// </summary>
public string[]? AlsoNotify { get; }
}
#nullable restore
#pragma warning restore
#pragma warning restore
Loading
Loading