RSCG – DecoratorGenerator
| name | DecoratorGenerator |
| nuget | https://www.nuget.org/packages/DecoratorGenerator/ |
| link | https://github.com/CodingFlow/decorator-generator |
| author | Leopoldo Fu |
adding decorator for classes/ interfaces
This is how you can use DecoratorGenerator .
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>
<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="DecoratorGenerator" Version="0.3.0" />
</ItemGroup>
</Project>
The code that you will use is
// See https://aka.ms/new-console-template for more information
using DecoratorDemo;
Console.WriteLine("Hello, World!");
IPerson person = new Person();
person = new LogPerson(person);
person.FirstName = "Andrei";
person.LastName = "Ignat";
Console.WriteLine(person.FullName());
var birthDate = new DateTime(1970, 4, 16);
var age = await person.CalculateAgeAsync(birthDate);
Console.WriteLine($"Age is {age}");
using System;
using System.Collections.Generic;
using System.Text;
namespace DecoratorDemo;
internal class Person : IPerson
{
public string FirstName { get; set; } = string.Empty;
public string LastName { get; set; } = string.Empty;
public string FullName()
{
return $"{FirstName} {LastName}";
}
public async Task<int> CalculateAgeAsync(DateTime birthDate)
{
await Task.Delay(100); // Simulate async work
var today = DateTime.Today;
var age = today.Year - birthDate.Year;
if (birthDate.Date > today.AddYears(-age)) age--;
return age;
}
}
using DecoratorGenerator;
using System;
using System.Collections.Generic;
using System.Text;
namespace DecoratorDemo;
[Decorate]
public interface IPerson
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string FullName();
public Task<int> CalculateAgeAsync(DateTime birthDate);
}
using System;
using System.Collections.Generic;
using System.Text;
namespace DecoratorDemo;
internal class LogPerson : PersonDecorator
{
public LogPerson(IPerson person) : base(person)
{
}
public override string FirstName
{
get
{
Console.WriteLine($"FirstName getter called, returning {base.FirstName}");
return base.FirstName;
}
set
{
Console.WriteLine($"FirstName setter called, setting value to {value}");
base.FirstName = value;
}
}
public override string FullName()
{
Console.WriteLine($"FullName() called for {FirstName} {LastName}" );
return base.FullName();
}
public override async Task<int> CalculateAgeAsync(DateTime birthDate)
{
Console.WriteLine($"CalculateAgeAsync called with birthDate: {birthDate.ToShortDateString()}");
return await base.CalculateAgeAsync(birthDate);
}
}
The code that is generated is
// <auto-generated/>
#nullable restore
namespace DecoratorDemo;
public abstract class PersonDecorator : IPerson
{
private IPerson person;
protected PersonDecorator(IPerson person) {
this.person = person;
}
public virtual string FirstName { get => person.FirstName; set => person.FirstName = value; }
public virtual string LastName { get => person.LastName; set => person.LastName = value; }
public virtual string FullName() {
return person.FullName();
}
public virtual System.Threading.Tasks.Task<int> CalculateAgeAsync(System.DateTime birthDate) {
return person.CalculateAgeAsync(birthDate);
}
}
Code and pdf at
https://ignatandrei.github.io/RSCG_Examples/v2/docs/DecoratorGenerator