Skip to content

Commit 64c4c6d

Browse files
Add Partial Property support for Reactive property (#172)
* Add Partial Property support for Reactive property * Update Tests * Update ReactiveCommand from base * Resolve merge conflict * Add Test and Documentation * Update Is Packable to false --------- Co-authored-by: Glenn <5834289+glennawatson@users.noreply.github.com>
1 parent 9e86c87 commit 64c4c6d

File tree

100 files changed

+638
-44
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

100 files changed

+638
-44
lines changed

README.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ This documentation covers using ReactiveUI Source Generators to simplify and enh
1111

1212
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:
1313

14-
- `[Reactive]`
14+
- `[Reactive]` With field and access modifiers, partial property support (C# 13 Visual Studio Version 17.12.0)
1515
- `[ObservableAsProperty]`
1616
- `[ObservableAsProperty(PropertyName = "ReadOnlyPropertyName")]`
1717
- `[ReactiveCommand]`
@@ -131,6 +131,23 @@ public partial class MyReactiveClass : ReactiveObject
131131
}
132132
```
133133

134+
### Usage Reactive property from partial property
135+
136+
Partial properties are supported in C# 13 and Visual Studio 17.12.0 and later.
137+
Both the getter and setter must be empty, and the `[Reactive]` attribute must be placed on the property.
138+
Override and Virtual properties are supported.
139+
Set Access Modifier is also supported on partial properties.
140+
141+
```csharp
142+
using ReactiveUI.SourceGenerators;
143+
144+
public partial class MyReactiveClass : ReactiveObject
145+
{
146+
[Reactive]
147+
public partial string MyProperty { get; set; }
148+
}
149+
```
150+
134151
## Usage ObservableAsPropertyHelper `[ObservableAsProperty]`
135152

136153
ObservableAsPropertyHelper is used to create a read-only property from an IObservable. The generated code will create a backing field and a property that returns the value of the backing field. The backing field is initialized with the value of the IObservable when the class is instantiated.

src/Directory.Packages.props

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
<PackageVersion Include="xunit.runner.console" Version="2.9.3" />
3636
<PackageVersion Include="xunit.runner.visualstudio" Version="3.0.1" />
3737
<PackageVersion Include="Xunit.StaFact" Version="1.2.69" />
38-
<PackageVersion Include="FluentAssertions" Version="8.0.0" />
38+
<PackageVersion Include="FluentAssertions" Version="8.0.1" />
3939
<PackageVersion Include="Microsoft.Reactive.Testing" Version="6.0.1" />
4040
<PackageVersion Include="PublicApiGenerator" Version="11.3.0" />
4141
<PackageVersion Include="coverlet.msbuild" Version="6.0.3" />
@@ -45,4 +45,4 @@
4545
<PackageVersion Include="Basic.Reference.Assemblies.Net80" Version="1.8.0" />
4646
<PackageVersion Include="Basic.Reference.Assemblies.Net80Windows" Version="1.8.0" />
4747
</ItemGroup>
48-
</Project>
48+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//HintName: ReactiveUI.SourceGenerators.AccessModifier.g.cs
2+
// Copyright (c) 2025 .NET Foundation and Contributors. All rights reserved.
3+
// Licensed to the .NET Foundation under one or more agreements.
4+
// The .NET Foundation licenses this file to you under the MIT license.
5+
// See the LICENSE file in the project root for full license information.
6+
7+
// <auto-generated/>
8+
#pragma warning disable
9+
#nullable enable
10+
namespace ReactiveUI.SourceGenerators;
11+
12+
/// <summary>
13+
/// AccessModifier.
14+
/// </summary>
15+
internal enum AccessModifier
16+
{
17+
Public,
18+
Protected,
19+
Internal,
20+
Private,
21+
InternalProtected,
22+
PrivateProtected,
23+
Init,
24+
}
25+
26+
/// <summary>
27+
/// InheritanceModifier.
28+
/// </summary>
29+
internal enum InheritanceModifier
30+
{
31+
None,
32+
Virtual,
33+
Override,
34+
New,
35+
}
36+
#nullable restore
37+
#pragma warning restore
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//HintName: ReactiveUI.SourceGenerators.ReactiveAttribute.g.cs
2+
// Copyright (c) 2025 .NET Foundation and Contributors. All rights reserved.
3+
// Licensed to the .NET Foundation under one or more agreements.
4+
// The .NET Foundation licenses this file to you under the MIT license.
5+
// See the LICENSE file in the project root for full license information.
6+
7+
using System;
8+
9+
// <auto-generated/>
10+
#pragma warning disable
11+
#nullable enable
12+
namespace ReactiveUI.SourceGenerators;
13+
14+
/// <summary>
15+
/// ReactiveAttribute.
16+
/// </summary>
17+
/// <seealso cref="Attribute" />
18+
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
19+
internal sealed class ReactiveAttribute : Attribute
20+
{
21+
/// <summary>
22+
/// Gets the AccessModifier of the set property.
23+
/// </summary>
24+
/// <value>
25+
/// The AccessModifier of the set property.
26+
/// </value>
27+
public AccessModifier SetModifier { get; init; }
28+
29+
/// <summary>
30+
/// Gets the InheritanceModifier of the property.
31+
/// </sumary>
32+
public InheritanceModifier Inheritance { get; init; }
33+
34+
/// <summary>
35+
/// Use Required attribute to indicate that the property is required.
36+
/// </summary>
37+
public bool UseRequired { get; init; }
38+
}
39+
#nullable restore
40+
#pragma warning restore

src/ReactiveUI.SourceGenerator.Tests/REACTIVE/ReactiveGeneratorTests.FromReactiveProperiesWithAttributes#ReactiveUI.SourceGenerators.ReactiveAttribute.g.verified.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace ReactiveUI.SourceGenerators;
1515
/// ReactiveAttribute.
1616
/// </summary>
1717
/// <seealso cref="Attribute" />
18-
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
18+
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
1919
internal sealed class ReactiveAttribute : Attribute
2020
{
2121
/// <summary>

src/ReactiveUI.SourceGenerator.Tests/REACTIVE/ReactiveGeneratorTests.FromReactiveProperiesWithAttributes#TestNs.TestVM.Properties.g.verified.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ namespace TestNs
1212
/// </summary>
1313
public partial class TestVM
1414
{
15+
1516
/// <inheritdoc cref="_test3"/>
1617
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
1718
[global::System.Runtime.Serialization.DataMemberAttribute()]

src/ReactiveUI.SourceGenerator.Tests/REACTIVE/ReactiveGeneratorTests.FromReactiveProperties#ReactiveUI.SourceGenerators.ReactiveAttribute.g.verified.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace ReactiveUI.SourceGenerators;
1515
/// ReactiveAttribute.
1616
/// </summary>
1717
/// <seealso cref="Attribute" />
18-
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
18+
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
1919
internal sealed class ReactiveAttribute : Attribute
2020
{
2121
/// <summary>

src/ReactiveUI.SourceGenerator.Tests/REACTIVE/ReactiveGeneratorTests.FromReactiveProperties#TestNs.TestVM.Properties.g.verified.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ namespace TestNs
1212
/// </summary>
1313
public partial class TestVM
1414
{
15+
1516
/// <inheritdoc cref="_test1"/>
1617
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
1718
public int Test1

src/ReactiveUI.SourceGenerator.Tests/REACTIVE/ReactiveGeneratorTests.FromReactivePropertiesWithAccess#ReactiveUI.SourceGenerators.ReactiveAttribute.g.verified.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace ReactiveUI.SourceGenerators;
1515
/// ReactiveAttribute.
1616
/// </summary>
1717
/// <seealso cref="Attribute" />
18-
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
18+
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
1919
internal sealed class ReactiveAttribute : Attribute
2020
{
2121
/// <summary>

src/ReactiveUI.SourceGenerator.Tests/REACTIVE/ReactiveGeneratorTests.FromReactivePropertiesWithAccess#TestNs.TestVM.Properties.g.verified.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ namespace TestNs
1212
/// </summary>
1313
public partial class TestVM
1414
{
15+
1516
/// <inheritdoc cref="_test2"/>
1617
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
1718
public int Test2

0 commit comments

Comments
 (0)