Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
e42d14a
Added AccessorAccessibility to Attributes
ShawnLaMountain Jun 21, 2025
1b66799
Update CD.yml for Testing
ShawnLaMountain Jun 21, 2025
2ec673f
Property generated by Source Generator now chooses its Accessibility …
ShawnLaMountain Jun 24, 2025
1804ffd
Merge branch 'main' of https://github.com/ShawnLaMountain/ThunderDesi…
ShawnLaMountain Jun 24, 2025
df51030
Update CD.yml for Testing
ShawnLaMountain Jun 24, 2025
0f68b38
Fixed issue with Generated property defaulting to Public if getter no…
ShawnLaMountain Jun 24, 2025
acb3180
Merge branch 'main' of https://github.com/ShawnLaMountain/ThunderDesi…
ShawnLaMountain Jun 24, 2025
832a8db
Update CD.yml for Testing
ShawnLaMountain Jun 24, 2025
3e5623f
Fixxing issue with missing AccessorAccess before Source Generator Pro…
ShawnLaMountain Jun 24, 2025
ff60306
Merge branch 'main' of https://github.com/ShawnLaMountain/ThunderDesi…
ShawnLaMountain Jun 24, 2025
691c50b
Update CD.yml for Testing
ShawnLaMountain Jun 24, 2025
1f5e912
Issues with getter and setter values
ShawnLaMountain Jun 24, 2025
a5cf1e8
Merge branch 'main' of https://github.com/ShawnLaMountain/ThunderDesi…
ShawnLaMountain Jun 24, 2025
5fc8c3e
Update CD.yml for Testing
ShawnLaMountain Jun 24, 2025
0a5e563
Fixing issues with getters and setters
ShawnLaMountain Jun 24, 2025
ed6ee11
Merge branch 'main' of https://github.com/ShawnLaMountain/ThunderDesi…
ShawnLaMountain Jun 24, 2025
d83b3b7
Update CD.yml for Testing
ShawnLaMountain Jun 24, 2025
db416dd
Still testing getter and setter
ShawnLaMountain Jun 24, 2025
bcf85ca
Merge branch 'main' of https://github.com/ShawnLaMountain/ThunderDesi…
ShawnLaMountain Jun 24, 2025
ff74128
Update CD.yml for Testing
ShawnLaMountain Jun 24, 2025
904bddc
Still trying to fix getter and setter
ShawnLaMountain Jun 24, 2025
46db30c
Merge branch 'main' of https://github.com/ShawnLaMountain/ThunderDesi…
ShawnLaMountain Jun 24, 2025
b3bb21a
Update CD.yml for Testing
ShawnLaMountain Jun 24, 2025
761d849
Still fixing getter and setter
ShawnLaMountain Jun 24, 2025
e725942
Merge branch 'main' of https://github.com/ShawnLaMountain/ThunderDesi…
ShawnLaMountain Jun 24, 2025
92bbf86
Update CD.yml for Testing
ShawnLaMountain Jun 24, 2025
b764a83
Working on getters and setters
ShawnLaMountain Jun 24, 2025
568ef12
Merge branch 'main' of https://github.com/ShawnLaMountain/ThunderDesi…
ShawnLaMountain Jun 24, 2025
55bff21
Update CD.yml for Testing
ShawnLaMountain Jun 24, 2025
4b9bfe6
Testing getters and setters
ShawnLaMountain Jun 24, 2025
56ed3f8
Merge branch 'main' of https://github.com/ShawnLaMountain/ThunderDesi…
ShawnLaMountain Jun 24, 2025
304bca4
Update CD.yml for Testing
ShawnLaMountain Jun 24, 2025
ef8f7b0
optimized the code now that things are working
ShawnLaMountain Jun 24, 2025
4759aa3
Merge branch 'main' of https://github.com/ShawnLaMountain/ThunderDesi…
ShawnLaMountain Jun 24, 2025
5d0b36f
Update CD.yml for Testing
ShawnLaMountain Jun 24, 2025
fd2c251
Created multiple constructors for BindablePropertyAttribute
ShawnLaMountain Jun 25, 2025
e4d0484
Merge branch 'main' of https://github.com/ShawnLaMountain/ThunderDesi…
ShawnLaMountain Jun 25, 2025
37bab75
Update CD.yml for Testing
ShawnLaMountain Jun 25, 2025
d21d6ad
Updated BindablePropertyAttributes
ShawnLaMountain Jun 25, 2025
1a9597b
Merge branch 'main' of https://github.com/ShawnLaMountain/ThunderDesi…
ShawnLaMountain Jun 25, 2025
ec60cca
Update CD.yml for Testing
ShawnLaMountain Jun 25, 2025
2d4832b
BindablePropertyAttribute, PropertyAttribute and Accessorccessibility…
ShawnLaMountain Jun 25, 2025
55309a1
Merge branch 'main' of https://github.com/ShawnLaMountain/ThunderDesi…
ShawnLaMountain Jun 25, 2025
4db9f85
Update CD.yml for Testing
ShawnLaMountain Jun 25, 2025
783e552
Reverted new constructors for BindablePropertyAttributes. Was causing…
ShawnLaMountain Jun 25, 2025
0c520f6
Merge branch 'main' of https://github.com/ShawnLaMountain/ThunderDesi…
ShawnLaMountain Jun 25, 2025
f894087
Update CD.yml for Testing
ShawnLaMountain Jun 25, 2025
203b79f
Update CD.yml for production
ShawnLaMountain Jun 25, 2025
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
6 changes: 3 additions & 3 deletions .github/workflows/CD.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,14 @@ jobs:
shell: pwsh

- name: Create NuGet Package
# run: nuget pack ThunderDesign.Net-PCL.nuspec -Version 1.1.4 -OutputDirectory ${{ env.PACKAGE_OUTPUT_DIRECTORY }}
# run: nuget pack ThunderDesign.Net-PCL.nuspec -Version 2.0.17 -OutputDirectory ${{ env.PACKAGE_OUTPUT_DIRECTORY }}
run: nuget pack ThunderDesign.Net-PCL.nuspec -Version ${{ github.event.release.tag_name }} -OutputDirectory ${{ env.PACKAGE_OUTPUT_DIRECTORY }}

- name: Archive NuGet Package
uses: actions/upload-artifact@v4
with:
# name: Package_${{ env.FILE_NAME}}.1.1.4
# path: ${{ env.PACKAGE_OUTPUT_DIRECTORY}}\${{ env.FILE_NAME}}.1.1.4.nupkg
# name: Package_${{ env.FILE_NAME}}.2.0.17
# path: ${{ env.PACKAGE_OUTPUT_DIRECTORY}}\${{ env.FILE_NAME}}.2.0.17.nupkg
name: Package_${{ env.FILE_NAME}}.${{ github.event.release.tag_name }}
path: ${{ env.PACKAGE_OUTPUT_DIRECTORY}}\${{ env.FILE_NAME}}.${{ github.event.release.tag_name }}.nupkg

Expand Down
142 changes: 128 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# ThunderDesign.Net-PCL.Threading
# ThunderDesign.Net-PCL.Threading
[![CI](https://github.com/ThunderDesign/ThunderDesign.Net-PCL.Threading/actions/workflows/CI.yml/badge.svg)](https://github.com/ThunderDesign/ThunderDesign.Net-PCL.Threading/actions/workflows/CI.yml)
[![CD](https://github.com/ThunderDesign/ThunderDesign.Net-PCL.Threading/actions/workflows/CD.yml/badge.svg)](https://github.com/ThunderDesign/ThunderDesign.Net-PCL.Threading/actions/workflows/CD.yml)
[![Nuget](https://img.shields.io/nuget/v/ThunderDesign.Net-PCL.Threading)](https://www.nuget.org/packages/ThunderDesign.Net-PCL.Threading)
Expand Down Expand Up @@ -107,19 +107,18 @@ With the source generator, you only need to annotate your fields:

```csharp
using ThunderDesign.Net.Threading.Attributes;

public partial class Person
{
[BindableProperty]
{
[BindableProperty]
private string _name;

[Property]
private int _age;
}
```

**What gets generated:**
- A public `Name` property with thread-safe getter/setter and `INotifyPropertyChanged` support.
- A public `Age` property with thread-safe getter/setter.
**What gets generated:**

```csharp
using System.ComponentModel;
Expand All @@ -130,7 +129,6 @@ using ThunderDesign.Net.Threading.Interfaces;
public partial class Person : IBindableObject, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;

protected readonly object _Locker = new object();

public string Name
Expand All @@ -150,18 +148,132 @@ public partial class Person : IBindableObject, INotifyPropertyChanged
You can now use your `Person` class like this:

```csharp
var person = new Person();
person.Name = "Alice";
person.Age = 30; // PropertyChanged event will be raised for Name changes if you subscribe to it.
var person = new Person();
person.Name = "Alice";
person.Age = 30;
// PropertyChanged event will be raised for Name changes if you subscribe to it.
```


**No need to manually implement** property notification, thread safety, or boilerplate code—the generator does it for you!

> For more advanced scenarios, you can use attribute parameters to control property behavior (e.g., read-only, also notify other properties, etc.).
> For more advanced scenarios, you can use attribute parameters to control property behavior (e.g., read-only, also notify other properties, or control accessor/property visibility).

---

----
### Advanced: Customizing Getter and Setter Accessors

You can control the visibility of the generated property's getter and setter using the `AccessorAccessibility` enum.
The property itself will use the most accessible (widest) of the getter or setter's accessibilities.

#### Example

```csharp
using ThunderDesign.Net.Threading.Attributes;
using ThunderDesign.Net.Threading.Enums;

public partial class Person
{
// Public getter, private setter (property will be public)
[BindableProperty(getter: AccessorAccessibility.Public, setter: AccessorAccessibility.Private)]
private string _name;

// Internal getter, protected setter (property will be internal)
[Property(getter: AccessorAccessibility.Internal, setter: AccessorAccessibility.Protected)]
private int _age;
}
```

**What gets generated:**
```csharp
public partial class Person
{
public string Name
{
get { return this.GetProperty(ref _name, _Locker); }
private set { this.SetProperty(ref _name, value, _Locker, true); }
}

internal int Age
{
internal get { return this.GetProperty(ref _age, _Locker); }
protected set { this.SetProperty(ref _age, value, _Locker); }
}
}

```

> The property will be as accessible as its most accessible accessor (getter or setter).
> The default for `getter`, and `setter` is `public` if not specified.

**Available options for `AccessorAccessibility`:**
- `Public`
- `Private`
- `Protected`
- `Internal`
- `ProtectedInternal`
- `PrivateProtected`

---

### Advanced: Notify Other Properties

You can notify other properties when a specific property changes by using the `alsoNotify` parameter in the `[BindableProperty]` attribute.

#### Example
```csharp
using ThunderDesign.Net.Threading.Attributes;

public partial class Person
{
[BindableProperty(alsoNotify: new[] { nameof(DisplayName) })]
private string _firstName;

[BindableProperty(alsoNotify: new[] { nameof(DisplayName) })]
private string _lastName;

public string DisplayName => $"{FirstName} {LastName}";
}
```

**What gets generated:**

```csharp
public partial class Person : IBindableObject, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected readonly object _Locker = new object();

public string FirstName
{
get { return this.GetProperty(ref _firstName, _Locker); }
set
{
if (this.SetProperty(ref _firstName, value, _Locker, true))
{
this.OnPropertyChanged(nameof(DisplayName));
}
}
}

public string LastName
{
get { return this.GetProperty(ref _lastName, _Locker); }
set
{
if (this.SetProperty(ref _lastName, value, _Locker, true))
{
this.OnPropertyChanged(nameof(DisplayName));
}
}
}

public string DisplayName => $"{FirstName} {LastName}";
}
```

> This feature is particularly useful for computed properties like `DisplayName` that depend on other properties.

---

## Installation

Expand Down Expand Up @@ -199,4 +311,6 @@ This can be overwritten durring creation or by setting Property `WaitOnNotifyCol
Observable Objects Property `WaitOnNotifyPropertyChanged` has been renamed to Property `WaitOnNotifying`.

Observable Collections Property `WaitOnNotifyCollectionChanged` has been removed and now uses Property `WaitOnNotifying`.
----
----


Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
using Microsoft.CodeAnalysis.CSharp.Syntax;
using System.Linq;

namespace ThunderDesign.Net_PCL.SourceGenerators
namespace ThunderDesign.Net.SourceGenerators.Helpers
{
internal static class PropertyGeneratorHelpers
{
Expand Down Expand Up @@ -74,7 +74,7 @@ public static PropertyFieldInfo GetFieldWithAttribute(GeneratorSyntaxContext con
}
}
}
return default(PropertyFieldInfo);
return default;
}

// Rule 2: Field must start with "_" followed by a letter, or a lowercase letter
Expand Down Expand Up @@ -123,17 +123,17 @@ public static bool EventExists(INamedTypeSymbol classSymbol, string eventName, I
public static bool MethodExists(
INamedTypeSymbol classSymbol,
string methodName,
ITypeSymbol[]? parameterTypes = null,
ITypeSymbol? returnType = null)
ITypeSymbol[] parameterTypes = null,
ITypeSymbol returnType = null)
{
return classSymbol.GetMembers()
.OfType<IMethodSymbol>()
.Any(m =>
m.Name == methodName &&
(parameterTypes == null ||
(m.Parameters.Length == parameterTypes.Length &&
m.Parameters.Length == parameterTypes.Length &&
m.Parameters.Select(p => p.Type.ToDisplayString())
.SequenceEqual(parameterTypes.Select(t => t.ToDisplayString())))) &&
.SequenceEqual(parameterTypes.Select(t => t.ToDisplayString()))) &&
(returnType == null || SymbolEqualityComparer.Default.Equals(m.ReturnType, returnType))
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>latest</LangVersion>
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
<RootNamespace>ThunderDesign.Net_PCL.SourceGenerators</RootNamespace>
<RootNamespace>ThunderDesign.Net.SourceGenerators</RootNamespace>
<IncludeBuildOutput>false</IncludeBuildOutput>
<IncludeAnalyzer>true</IncludeAnalyzer>
<!-- NuGet package metadata -->
Expand Down
Loading
Loading