A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/StefH/FluentBuilder below:

StefH/FluentBuilder: A project which uses Source Generation to create a FluentBuilder for a specified model or DTO

Projects

See also these blogs:

⭐ CSharp.SourceGenerators.Extensions

See this page.

A project which uses Source Generation to create a FluentBuilder for a specified model or DTO.

This project is based on Tom Phan : "auto-generate-builders-using-source-generator-in-net-5".

📝 Note that FluentBuilder version 0.10.0 requires at least Visual Studio 17.11.5

1️⃣ Usage on a existing class

Annotate an existing class with [FluentBuilder.AutoGenerateBuilder] to indicate that a FluentBuilder should be generated for this class:

using FluentBuilder;

[AutoGenerateBuilder]
public class User
{
    public string FirstName { get; set; }

    public string LastName { get; set; }

    public DateTime? Date { get; set; }

    [FluentBuilderIgnore] // Add this attribute to ignore this property when generating a FluentBuilder.
    public int Age { get; set; }

    public int Answer { get; set; } = 42; // When a default value is set, this value is also set as default in the FluentBuilder.
}
AutoGenerateBuilder - attribute

This attribute has 4 arguments:

using System;
using FluentBuilder;

namespace Test;

class Program
{
    static void Main(string[] args)
    {
        var user = new UserBuilder()
            .WithFirstName("Test")
            .WithLastName("User")
            .Build();

        Console.WriteLine($"{user.FirstName} {user.LastName}");
    }
}
Use FluentBuilder when the class has a default (parameter-less) constructor
using FluentBuilder;

[AutoGenerateBuilder]
public class User
{
    public string FirstName { get; set; }

    public string LastName { get; set; }

    public DateTime? Date { get; set; }

    public User()
    {
        FirstName = "test";
    }
}
using System;
using FluentBuilder;

namespace Test;

class Program
{
    static void Main(string[] args)
    {
        var user = new UserBuilder()
            .WithLastName("User")
            .Build(false); // ⭐ Provide `false` for `useObjectInitializer` here.

        Console.WriteLine($"{user.FirstName} {user.LastName}");
    }
}
Use FluentBuilder when the class has a constructor with parameters
using FluentBuilder;

[AutoGenerateBuilder]
public class User
{
    public string FirstName { get; set; }

    public string LastName { get; set; }

    public DateTime? Date { get; set; }

    public User(string first)
    {
        FirstName = first;
    }
}
using System;
using FluentBuilder;

namespace Test;

class Program
{
    static void Main(string[] args)
    {
        var user = new UserBuilder()
            .UsingConstructor("First")  // ⭐ Use `UsingConstructor` here.
            .WithLastName("User")
            .Build();

        Console.WriteLine($"{user.FirstName} {user.LastName}");
    }
}
Using FluentBuilder when a class has an Array or IEnumerable<T> property
using FluentBuilder;

[AutoGenerateBuilder]
public class UserDto
{
    public IEnumerable<EmailDto> SecondaryEmails { get; set; }

    public int[] IntArray { get; set; }
}
var user = new UserDtoBuilder()
    .WithIntArray(ib => ib         // 👈 Use a Integer Array Builder
        .Add(1)                    // Add a normal integer

        .Add(() => 2)              // Add an integer with a Func<>
        .Build()
    )
    .WithSecondaryEmails(sb => sb  // 👈 Use a EmailDto IEnumerable Builder
        .Add(new EmailDto())       // Add a normal EmailDto using new() constructor

        .Add(() => new EmailDto()) // Add an EmailDto using Func<>

        .Add(eb => eb              // 👈 Use a EmailDto IEnumerable Builder to add an EmailDto
            .WithPrimary(true)
            .Build()
        )
        .Build()
    )
    .Build();
Using FluentBuilder when a class has an IDictionary<TKey, TValue> property
using FluentBuilder;

[AutoGenerateBuilder]
public class UserDto
{
    public IDictionary<string, int> Tags { get; set; }
}
var user = new UserDtoBuilder()
    .WithTags(db => db      // 👈 Use a Dictionary<TKey, TValue> Builder
        .Add("test", 123)   // Add a key with value

        .Add(() => new KeyValuePair<string, int>("x", 42)) // Add a KeyValuePair with a Func<>
        .Build()
    )
    .Build();
2️⃣ Define a class which needs to act as a builder

This scenario is very usefull when you cannot modify the class to annotate it.

Create a public and partial builder class

And annotate this class with [AutoGenerateBuilder(typeof(XXX))] where XXX is the type for which you want to generate a FluentBuilder.

using FluentBuilder;

[AutoGenerateBuilder(typeof(UserDto))]
public partial class MyUserDtoBuilder
{
}

If you are using C# 11.0 (.NET 7 and up), you can also use the generic AutoGenerateBuilder<T>-attribute. Example:

using FluentBuilder;

[AutoGenerateBuilder<UserDto>()]
public partial class MyUserDtoBuilder
{
}
using System;
using FluentBuilder;

namespace Test;

class Program
{
    static void Main(string[] args)
    {
        var user = new MyUserDtoBuilder() // 👈 Just use your own Builder
            .WithFirstName("Test")
            .WithLastName("User")
            .Build();

        Console.WriteLine($"{user.FirstName} {user.LastName}");
    }
}

By default, the AsBuilder extension method is also generated which allows you to change an existing instance using the With-methods from the builder.

Example:

var user = await dbContext.Users.FirstAsync();

user = user.AsBuilder() // Lifts the user into a builder instance
    .WithLastName("Different LastName") // Updates "LastName" while keeping existing properties
    .Build(); // Changes are applied

await dbContext.SaveChangesAsync(); // User's LastName property is updated.

Since version 0.8.0, this FluentBuilder will only generate the With*** methods. If you want the builder to also generate the Without*** methods, add the enum FluentBuilderMethods.WithAndWithout to the attribute.

using FluentBuilder;

[AutoGenerateBuilder(typeof(UserDto), FluentBuilderMethods.WithAndWithout)]
public partial class MyUserDtoBuilder
{
}

Entity Framework Extensions and Dapper Plus are major sponsors and proud to contribute to the development of FluentBuilder and CSharp.SourceGenerators.Extensions.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4