[Interface2NullObject]Implementation–part2

Introducing rscg_Interface_to_null_object: Simplifying the Null Object Pattern

I’m excited to announce the release of my new project, rscg_Interface_to_null_object. This project aims to simplify the implementation of the Null Object Pattern in C# by automatically generating null object classes from interfaces.

Architecture Overview

The project is composed of two main components:

  1. Attribute Project: This project contains the attribute that you can apply to interfaces for which you want to generate null object classes.
  2. Generator Project: This project contains the logic for intercepting the interfaces with the attribute and generating the corresponding null object classes.

How It Works

Intercepting the Attribute

The generator project first intercepts the attribute applied to the interfaces. This allows it to identify which interfaces need null object classes.

        var classesToApplySortable = context.SyntaxProvider.ForAttributeWithMetadataName(
"InterfaceToNullObject.ToNullObjectAttribute",
IsAppliedOnInterface,
FindAttributeDataExpose
)
.Collect()
.SelectMany((data, _) => data.Distinct())
.Collect();

Generating Classes

Once the interfaces are identified, the generator uses a RazorBlade template to create the null object classes. This ensures that the generated classes are consistent and follow best practices.

@inherits RazorBlade.PlainTextTemplate<rscg_Interface_to_null_object.DataFromExposeInterface>
@{
    string nameClass = Model.Name.StartsWith("I")?Model.Name.Substring(1):Model.Name;
    nameClass += "_null";
}
// <auto-generated>
    //     This code was generated by a tool :@Generated.rscg_Interface_to_null_object.TheAssemblyInfo.AssemblyName
    //     Runtime Version: @Generated.rscg_Interface_to_null_object.TheAssemblyInfo.GeneratedNameNice
    //     DateOfTool : @Generated.rscg_Interface_to_null_object.TheAssemblyInfo.DateGeneratedUTC.ToString("yyyy-MM-dd HH:mm:ss")
    //     Changes to this file may cause incorrect behavior and will be lost if
    //     the code is regenerated.
    // </auto-generated>
//------------------------------------------------------------------------------
/// <summary>
    /// This static partial class contains extension methods for sorting collections of @Model.Name objects.
    /// </summary>

 #nullable enable
 #pragma warning disable CS8603
 #pragma warning disable CS8625
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
[global::System.CodeDom.Compiler.GeneratedCode("GeneratorName","@Generated.rscg_Interface_to_null_object.TheAssemblyInfo.DateGeneratedUTC.ToString("yyyy.1MMdd.1HHmm.1ss")")]
public partial class @(nameClass) : @Model.FullName
{
@foreach(var prop in Model.props){
    <text>
        public virtual @prop.Type @prop.Name { get; set; } = default(@prop.Type);
    </text>
}
@foreach (var func in Model.functions)
{
    <text>
        public virtual @func.ReturnType @Model.DisplayFunc(func) { return default(@func.ReturnType); }
    </text>
}

}

#nullable restore
#pragma warning restore CS8603
#pragma warning restore CS8625

Getting Started

To get started with rscg_Interface_to_null_object, you can add the NuGet packages to your project and apply the attribute to your interfaces. The generator will take care of the rest, creating the necessary null object classes for you.

For more details and examples, check out the GitHub repository.

Happy coding!