Amadevus.RecordGenerator
ℹ This documentation is for v0.6 of RecordGenerator.
Description
C# Record Generator makes creating immutable record types a breeze! Just adorn your data type with [Record]
attribute and keep your code clean and simple. The backing code is generated on build-time, including IntelliSense support (just save the file, Visual Studio will make a build in background).
Table of contents
Installation
As it is a NuGet, it’s really simple:
- From terminal
dotnet add package Amadevus.RecordGenerator
- Package Manager
Install-Package Amadevus.RecordGenerator
- Or from
Manage NuGet packages
search forAmadevus.RecordGenerator
Usage
using Amadevus.RecordGenerator;
namespace Example
{
[Record]
sealed partial class Foo
{
public string Bar { get; }
}
}
As you can see, it’s very nice and easy. You just have to decorate your type
with [Record]
attribute and voilà, you have made yourself a record type!
Using generated features:
using System;
using Amadevus.RecordGenerator;
namespace QuickDemo
{
[Record(Features.Default | Features.Equality)]
public sealed partial class Contact
{
public int Id { get; }
public string Name { get; }
public string Email { get; }
public DateTime? Birthday { get; }
}
public static class Program
{
public static void Main()
{
var adam = new Contact.Builder
{
Id = 1,
Name = "Adam Demo",
Email = "foo@bar.com"
}.ToImmutable();
var adamWithBday = adam.WithBirthday(DateTime.UtcNow);
Console.WriteLine("Pretty display: " + adamWithBday);
// Pretty display: { Id = 1, Name = Adam Demo, Email = foo@bar.com, Birthday = 06.01.2020 23:17:06 }
Console.WriteLine("Check equality: " + adam.Equals(adamWithBday));
// Check equality: False
Console.WriteLine("Check equality: " + adam.Equals(new Contact(1, "Adam Demo", "foo@bar.com", null)));
// Check equality: True
}
}
}
The above is taken from QuickDemo sample
What does it mean, a record type?
A record type is an immutable named container for a bunch of objects (properties). As it is, C# doesn’t provide an easy way to create immutable types - that’s where RecordGenerator comes to the rescue!
What do I get?
The generator creates new partial for your type with additional members. The generator first
acquires a list of record entries - public properties that are read-only and auto-implemented
(which basically means they’re public SomeType SomeName { get; }
). Then it generates additional
members, depending on features selected in [Record(Features)]
attribute. (If nothing is selected, Default
value is used)
Features
The [Flags] enum Features
has the following values:
Feature | Generated Members | Description |
---|---|---|
Constructor |
.ctor , OnConstructed |
Has a parameter for every record entry, and assigns those parameters to corresponding auto-properties. At the end, the partial method OnConstructed is invoked. |
Withers |
WithBar , Update |
With -methods which take single record entry parameter and return new record instance with all values of record entries taken from current instance, except the parameter one which is changed to the parameter value. Update is a constructor forward. |
ToString |
ToString |
Generates an override that replicates an anonymous class’s ToString behavior. |
Builder |
Builder , ToBuilder |
Nested class which has the same record entries as the record, but read-write, and a ToImmutable method that creates a record instance with builder’s values. ToBuilder method returns a new builder instance with record’s values copied. |
Deconstruct |
Deconstruct |
Method which enables deconstruction of record into a list of variables like tuples do since C# 7.0 (ValueTuple). See Microsoft docs: Deconstruct. |
ObjectEquals |
object.Equals(object) , object.GetHashCode() |
Overrides that use record entries for comparisons and hash calculations. |
EquatableEquals |
IEquatable<Foo>.Equals(Foo) |
Implements the interface. |
OperatorEquals |
== , != |
Implements the operators. |
Equality |
- | Bundle of ObjectEquals , EquatableEquals , OperatorEquals features. |
Default |
- | Bundle of all above features, except Equality . |
Examples
- Person - with Default and Equality features
- Enclosed type (History.Entry) with default features
Diagnostics
The Amadevus.RecordGenerator.Analyzers
package (pulled in by main package) provides
diagnostics/codefixes that help you use Records correctly. See Analyzers.
Requirements
It is a development-only package, and the generation also works with CLI builds, both using dotnet
and msbuild
. The Attributes
target netstandard1.0
(the only compile-time dependecy).
It on depends dotnet
CLI to run the underlying CodeGeneration.Roslyn.Tool
,
which in turn requires .NET Core App v2.1
runtime (or later).
Roslyn Analyzer with CodeFix, to be supported in IDE, requires Visual Studio 2017+ or VS Code v1.19+.
If you want to use packages separately, there is more work to do.
- First of all, you can define your own
RecordAttribute
(instead of referencing the Attributes package); it needs to have the same name and[CodeGeneration]
attribute applied, same as the one defined in the Attributes package. - The project where code will be generated needs to reference
Amadevus.RecordGeneration.Generators
andCodeGeneration.Roslyn.Tool
packages. - Analyzers package is optional.
Development
To build the solution, .NET Core SDK v3.1.100 is required, as specified in global.json
.
Credits
Amadevus.RecordGenerator
wouldn’t work if not for @AArnott AArnott’s CodeGeneration.Roslyn.
Analyzers in Amadevus.RecordGenerator.Analyzers
were inspired by xUnit.net’s analyzers.
Contributions
All contributions are welcome, as well as critique. If you have any issues, problems or suggestions - please open an issue.
Visual Studio logo ™ Microsoft Corporation, used without permission.
RecordGenerator logo (on top) © 2017 Amadeusz Sadowski, all rights reserved.