boilerplatezero 1.0.2
See the version list below for details.
dotnet add package boilerplatezero --version 1.0.2
NuGet\Install-Package boilerplatezero -Version 1.0.2
<PackageReference Include="boilerplatezero" Version="1.0.2"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
paket add boilerplatezero --version 1.0.2
#r "nuget: boilerplatezero, 1.0.2"
// Install boilerplatezero as a Cake Addin #addin nuget:?package=boilerplatezero&version=1.0.2 // Install boilerplatezero as a Cake Tool #tool nuget:?package=boilerplatezero&version=1.0.2
boilerplatezero
boilerplatezero (BPZ) is a collection of C# source generators that simplifies the code that needs to be written for common C# patterns.
WPF Dependency Property Generator
Dependency properties in WPF are great! However, they do require quite a bit of ceremony in order to define one. Luckily, dependency properties (and attached properties) always follow the same pattern when implemented. As such, this kind of boilerplate code is the perfect candidate for a source generator.
The dependency property generator in BPZ works by identifying DependencyProperty
and DependencyPropertyKey
fields that are initialized with calls to appropriately-name Gen
or GenAttached
methods.
When this happens, the source generator adds private static classes as nested types inside your class & implements the dependency property for you.
🛠 Example Dependency Property
// Dependency property written idiomatically:
private static readonly DependencyPropertyKey FooPropertyKey = DependencyProperty.RegisterReadOnly(nameof(Foo), typeof(string), typeof(MyClass), null);
public static readonly DependencyProperty FooProperty = FooPropertyKey.DependencyProperty;
public string Foo
{
get => (string)this.GetValue(FooProperty);
private set => this.SetValue(FooPropertyKey, value);
}
// Dependency property written with BPZ:
private static readonly DependencyPropertyKey FooPropertyKey = Gen.Foo<string>();
🛠 Example Attached Property
// Attached property written idiomatically:
private static readonly DependencyPropertyKey BarPropertyKey = DependencyProperty.RegisterAttachedReadOnly("Bar"), typeof(string), typeof(MyClass), null);
public static readonly DependencyProperty BarProperty = BarPropertyKey.DependencyProperty;
public static string GetBar(DependencyObject d) => (string)d.GetValue(BarProperty);
private static void SetBar(DependencyObject d, string value) => d.SetValue(BarPropertyKey, value);
// Attached property written with BPZ:
private static readonly DependencyPropertyKey BarPropertyKey = GenAttached.Bar<string>();
🛠 Generated Code
Here's an example of 👩💻 hand-written code & the corresponding 🤖 generated code.
Note that the default value for the dependency property is specified in the user's code & the documentation comment on IdPropertyKey
is copied to the generated Id
property.
// 👩💻 Widget.cs
namespace Goodies
{
public partial class Widget : DependencyObject
{
/// <Summary>Gets the ID of this instance.</Summary>
protected static readonly DependencyPropertyKey IdPropertyKey = Gen.Id("<unset>");
}
}
// 🤖 Widget.g.cs (actual name may vary)
namespace Goodies
{
partial class Widget
{
public static readonly DependencyProperty IdProperty = IdPropertyKey.DependencyProperty;
/// <Summary>Gets the ID of this instance.</Summary>
public string Id
{
get => (string)this.GetValue(IdProperty);
protected set => this.SetValue(IdPropertyKey, value);
}
private static partial class Gen
{
public static DependencyPropertyKey Id<T>(T defaultValue)
{
PropertyMetadata metadata = new PropertyMetadata(defaultValue);
return DependencyProperty.RegisterReadOnly("Id", typeof(T), typeof(Widget), metadata);
}
}
}
}
✨ Features
- generates instance properties for dependency properties
- generates static methods for attached properties
- optional default values
- supports nullable types
public static readonly DependencyProperty IsCheckedProperty = Gen.IsChecked<bool?>(false); public static readonly DependencyProperty NameProperty = Gen.Name<string?>();
- access modifiers are preserved on generated members
- documentation is preserved (for dependency properties) on generated members
- generates dependency property fields for read-only properties (if necessary)
// 👩💻 user // Instance field `FooProperty` is defined, so it will not be generated. // Access modifiers for generated get/set of the `Foo` instance property will match the property & key. private static readonly DependencyPropertyKey FooPropertyKey = GenAttached.Foo(3.14f); protected static readonly DependencyProperty FooProperty = FooPropertyKey.DependencyProperty; // Instance field `BarProperty` is not defined, so it will be generated. private static readonly DependencyPropertyKey BarPropertyKey = Gen.Bar<Guid>(); // 🤖 generated protected float Foo { get => (float)this.GetValue(FooProperty); private set => this.SetValue(FooPropertyKey, value); } public static readonly DependencyProperty BarProperty = BarPropertyKey.DependencyProperty; public System.Guid Bar { get => (System.Guid)this.GetValue(BarProperty); private set => this.SetValue(BarPropertyKey, value); }
- attached properties may constrain their target type by specifying a generic type parameter on
GenAttached
// 👩💻 user // Attached property `Standard` may be used with any dependency object. public static readonly DependencyProperty StandardProperty = GenAttached.Standard("🍕"); // Attached property `IsFancy` may only be used with objects of type <see cref="Widget"/>. public static readonly DependencyProperty IsFancyProperty = GenAttached<Goodies.Widget>.IsFancy(true); // 🤖 generated public static string GetStandard(DependencyObject d) => (string)d.GetValue(StandardProperty); public static void SetStandard(DependencyObject d, string value) => d.SetValue(StandardProperty, value); public static bool GetIsFancy(Goodies.Widget d) => (bool)d.GetValue(IsFancyProperty); public static void SetIsFancy(Goodies.Widget d, bool value) => d.SetValue(IsFancyProperty, value);
Learn more about Target Frameworks and .NET Standard.
-
.NETStandard 2.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
2.0.0 | 583 | 2/6/2023 |
2.0.0-beta | 404 | 2/6/2023 |
1.8.0 | 13,036 | 6/6/2022 |
1.7.2 | 838 | 5/23/2022 |
1.7.1 | 1,341 | 10/16/2021 |
1.7.0 | 436 | 7/21/2021 |
1.6.0 | 413 | 7/6/2021 |
1.5.2 | 450 | 7/3/2021 |
1.5.1 | 378 | 6/26/2021 |
1.5.0 | 394 | 6/13/2021 |
1.4.1 | 531 | 1/2/2021 |
1.4.0 | 431 | 12/29/2020 |
1.3.0 | 361 | 12/29/2020 |
1.2.0 | 460 | 12/4/2020 |
1.1.0 | 487 | 11/29/2020 |
1.0.2 | 443 | 11/28/2020 |
1.0.1 | 495 | 11/26/2020 |
1.0.0 | 425 | 11/26/2020 |