Najlot.Audit.SourceGenerator

RSCG – Najlot.Audit.SourceGenerator    

name Najlot.Audit.SourceGenerator
nuget https://www.nuget.org/packages/Najlot.Audit.SourceGenerator/
link https://github.com/najlot/Audit
author Najlot

Generates audit/change-tracking code at compile time — detects which properties changed between two snapshots of an object.

How to use

1. Mark your entity and a partial provider with [AuditProvider]:

“`charp

[AuditProvider]

public partial class Person

{

public string FirstName { get; set; } = string.Empty;

public string LastName { get; set; } = string.Empty;

public int Id { get; set; }

}

[AuditProvider]

public partial class PersonAuditProvider

{

[AuditIgnore(nameof(Person.Id))]

public static partial IEnumerable GetPropertyValues(Person entity);

}

“`

2. Take a snapshot, mutate, then get changes:

“`charp

var audit = new Audit();

audit.RegisterProvider();

var snapshot = audit.CreateSnapshot(p);

p.LastName = “Ignat”;

foreach (var change in snapshot.GetChanges())

Console.WriteLine($”{change.Path}: {change.OldValue} → {change.NewValue}”);

“`

You can use for Property-level change tracking / audit logs at compile time.

Supports [AuditIgnore] to exclude properties.

  

This is how you can use Najlot.Audit.SourceGenerator .

The code that you start with is


<project sdk="Microsoft.NET.Sdk">

  <propertygroup>
    <outputtype>Exe</outputtype>
    <targetframework>net10.0</targetframework>
    <implicitusings>enable</implicitusings>
    <nullable>enable</nullable>
  </propertygroup>

  <itemgroup>
    <packagereference version="0.0.1" include="Najlot.Audit">
    <packagereference version="0.0.1" include="Najlot.Audit.SourceGenerator">
  </packagereference>

	<propertygroup>
		<emitcompilergeneratedfiles>true</emitcompilergeneratedfiles>
		<compilergeneratedfilesoutputpath>$(BaseIntermediateOutputPath)\GX</compilergeneratedfilesoutputpath>
	</propertygroup>

</packagereference>


The code that you will use is


using AuditDemo;
using Najlot.Audit;

Person p = new() { Id = 1, FirstName = "John", LastName = "Doe" };

var audit = new Audit();
audit.RegisterProvider<personauditprovider>();
var snapshot = audit.CreateSnapshot(p);

p.LastName = "Ignat";
p.FirstName = "Andrei";
var changes= snapshot.GetChanges().ToArray();
foreach (var change in changes)
{
    Console.WriteLine($"Property: {change.Path}, Old Value: {change.OldValue}, New Value: {change.NewValue}");
}


using Najlot.Audit;
using Najlot.Audit.Attributes;

namespace AuditDemo;

[AuditProvider]
public partial class Person
{
    public string FirstName { get; set; }= string.Empty;
    public string LastName { get; set; }= string.Empty;
    public string FullName() =&gt; $"{FirstName} {LastName}";

    public int Id { get; set; }
}


[AuditProvider]
public partial class PersonAuditProvider
{
    [AuditIgnore(nameof(Person.Id))]
    public static partial IEnumerable<propertyvalue> GetPropertyValues(Person entity);
}

   The code that is generated is

// <auto-generated>
#nullable enable
namespace AuditDemo
{
    public partial class PersonAuditProvider
    {
        public static partial global::System.Collections.Generic.IEnumerable<global::najlot.audit.propertyvalue> GetPropertyValues(global::AuditDemo.Person entity)
        {
            yield return new global::Najlot.Audit.PropertyValue("FirstName", entity.FirstName);
            yield return new global::Najlot.Audit.PropertyValue("LastName", entity.LastName);
        }

    }
}

// <auto-generated>
#nullable enable
using Najlot.Audit;

namespace AuditDemo
{
    public static class AuditRegistrationExtensions_AuditDemo
    {
        public static global::Najlot.Audit.IAudit RegisterAuditDemoAuditProviders(this global::Najlot.Audit.IAudit audit)
        {
            audit.Register<global::auditdemo.person>(global::AuditDemo.PersonAuditProvider.GetPropertyValues);
            return audit;
        }
    }
}

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/Najlot.Audit.SourceGenerator


Posted

in

, ,

by

Tags: