RSCG – BuilderGenerator

RSCG – BuilderGenerator
 
 

name BuilderGenerator
nuget https://www.nuget.org/packages/BuilderGenerator/
link https://github.com/MelGrubb/BuilderGenerator
author Mell Grubb

Generating Builder class for an object

 

This is how you can use BuilderGenerator .

The code that you start with is


<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net7.0</TargetFramework>
  </PropertyGroup>

	  <PropertyGroup>
        <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
        <CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
    </PropertyGroup>

	  <ItemGroup>
	    <PackageReference Include="BuilderGenerator" Version="2.3.0" />
	  </ItemGroup>

</Project>


The code that you will use is


using Builder;

var pOld = new Person();
pOld.FirstName = "Andrei";
pOld.LastName = "Ignat";
pOld.MiddleName = "G";
var build = new PersonBuilder()
    .WithFirstName(pOld.FirstName)
    .WithMiddleName("")
    .WithLastName(pOld.LastName)
    ;
    
var pNew = build.Build();
System.Console.WriteLine(pNew.FullName());
System.Console.WriteLine(pOld.FullName());



namespace Builder;
public class Person
{
    public string FirstName { get; set; }
    public string? MiddleName { get; set; }
    public string LastName { get; set; }

    public string FullName()
    {
        return FirstName + " " + MiddleName + " "+LastName;
    }
    
}



namespace Builder;

[BuilderGenerator.BuilderFor(typeof(Person))]
public partial class PersonBuilder
{
}

 

The code that is generated is

#nullable disable

namespace BuilderGenerator
{
    /// <summary>Base class for object builder classes.</summary>
    /// <typeparam name="T">The type of the objects built by this builder.</typeparam>
    public abstract class Builder<T> where T : class
    {
        /// <summary>Gets or sets the object returned by this builder.</summary>
        /// <value>The constructed object.</value>
        #pragma warning disable CA1720 // Identifier contains type name
        protected System.Lazy<T> Object { get; set; }
        #pragma warning restore CA1720 // Identifier contains type name

        /// <summary>Builds the object instance.</summary>
        /// <returns>The constructed object.</returns>
        public abstract T Build();

        protected virtual void PostProcess(T value)
        {
        }

        /// <summary>Sets the object to be returned by this instance.</summary>
        /// <param name="value">The object to be returned.</param>
        /// <returns>A reference to this builder instance.</returns>
        public Builder<T> WithObject(T value)
        {
            Object = new System.Lazy<T>(() => value);

            return this;
        }
    }
}

namespace BuilderGenerator
{
    [System.AttributeUsage(System.AttributeTargets.Class)]
    public class BuilderForAttribute : System.Attribute
    {
        public bool IncludeInternals { get; }
        public System.Type Type { get; }

        public BuilderForAttribute(System.Type type, bool includeInternals = false)
        {
            IncludeInternals = includeInternals;
            Type = type;
        }
    }
}

#nullable disable

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by BuilderGenerator at 2023-10-02T22:28:35 in 10.3936ms.
// </auto-generated>
//------------------------------------------------------------------------------
using System.CodeDom.Compiler;


namespace Builder
{
    public partial class PersonBuilder : BuilderGenerator.Builder<Builder.Person>
    {
        public System.Lazy<string> FirstName = new System.Lazy<string>(() => default(string));
        public System.Lazy<string> LastName = new System.Lazy<string>(() => default(string));
        public System.Lazy<string?> MiddleName = new System.Lazy<string?>(() => default(string?));

        public override Builder.Person Build()
        {
            if (Object?.IsValueCreated != true)
            {
                Object = new System.Lazy<Builder.Person>(() =>
                {
                    var result = new Builder.Person
                    {
                        FirstName = FirstName.Value,
                        LastName = LastName.Value,
                        MiddleName = MiddleName.Value,
                    };

                    return result;
                });

                PostProcess(Object.Value);
            }

            return Object.Value;
        }

        public PersonBuilder WithFirstName(string value)
        {
            return WithFirstName(() => value);
        }

        public PersonBuilder WithFirstName(System.Func<string> func)
        {
            FirstName = new System.Lazy<string>(func);
            return this;
        }

        public PersonBuilder WithoutFirstName()
        {
            FirstName = new System.Lazy<string>(() => default(string));
            return this;
        }

        public PersonBuilder WithLastName(string value)
        {
            return WithLastName(() => value);
        }

        public PersonBuilder WithLastName(System.Func<string> func)
        {
            LastName = new System.Lazy<string>(func);
            return this;
        }

        public PersonBuilder WithoutLastName()
        {
            LastName = new System.Lazy<string>(() => default(string));
            return this;
        }

        public PersonBuilder WithMiddleName(string? value)
        {
            return WithMiddleName(() => value);
        }

        public PersonBuilder WithMiddleName(System.Func<string?> func)
        {
            MiddleName = new System.Lazy<string?>(func);
            return this;
        }

        public PersonBuilder WithoutMiddleName()
        {
            MiddleName = new System.Lazy<string?>(() => default(string?));
            return this;
        }
    }
}

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/BuilderGenerator