RSCG_Templating by Andrei Ignat
Nuget / site data
Details
Info
Name: RSCG_Templating
Roslyn Templating for all
Author: Andrei Ignat
NuGet: https://www.nuget.org/packages/RSCG_Templating/
https://www.nuget.org/packages/RSCG_TemplatingCommon
You can find more details at https://github.com/ignatandrei/rscg_templating/
Original Readme
RSCG_Templating
Templating for generating everything from classes, methods from a Roslyn Code Generator
Templating is in SCRIBAN form
How to use
Add reference to
<ItemGroup>
<PackageReference Include="RSCG_Templating" Version="2023.1007.724" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
<PackageReference Include="RSCG_TemplatingCommon" Version="2023.1007.724" />
</ItemGroup>
<!-- this is just for debug purposes -->
<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
</PropertyGroup>
<!-- those are the templates files, see IGenerateDataFromClass -->
<ItemGroup>
<AdditionalFiles Include="ClassTypeName.txt" />
<AdditionalFiles Include="ClassPropByName.txt" />
</ItemGroup>
Then add additional files , for example
//autogenerated by RSCG_Templating version {{data.Version}} from file {{fileName}}
namespace {{data.nameSpace}} {
partial class {{data.className}} {
public string MyTypeName = "{{data.nameSpace}}.{{data.className}}";
}//end class
}//end namespace
Now add
//can have multiple attributes on partial classes
[IGenerateDataFromClass("ClassTypeName")]
public partial class Person
Advanced uses
For the moment , RSCG_Templating generates definition for a class with properties + methods . See example for generating enum from properties and setting properties by name
var x = new Person();
Console.WriteLine("The generated string type is "+x.MyTypeName);
x.FirstName = "Andrei";
//set last name via prop
x.SetPropValue(ePerson_Properties.LastName, "Ignat");
Console.WriteLine("called directly first name : " + x.FirstName);
Console.WriteLine("called via enum of prop first name : " + x.GetPropValue(ePerson_Properties.FirstName));
Console.WriteLine("called get property :" + x.GetPropValue(ePerson_Properties.Name));
See example at https://github.com/ignatandrei/RSCG_Templating/tree/main/src/RSCG_Templating
More templates
- Template for having the class type name: ClassTypeName
- Template for having the class properties as enum : ClassPropByName
- Template for setting properties after name : ClassPropByName
About
Templating every your data ( starting with class)
How to use
Example ( source csproj, source files )
- CSharp Project
- Program.cs
- Person.cs
- ClassPropByName.txt
- ClassTypeName.txt
This is the CSharp Project that references RSCG_Templating
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<AdditionalFiles Include="ClassTypeName.txt" />
<AdditionalFiles Include="ClassPropByName.txt" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="RSCG_Templating" Version="2023.1022.1748" OutputItemType="Analyzer" />
<PackageReference Include="RSCG_TemplatingCommon" Version="2023.1022.1748" />
</ItemGroup>
<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
</PropertyGroup>
</Project>
This is the use of RSCG_Templating in Program.cs
using RSCG_TemplatingDemo;
var x = new Person();
Console.WriteLine("The generated string type is " + x.MyTypeName);
x.FirstName = "Andrei";
//set last name via prop
x.SetPropValue(ePerson_Properties.LastName, "Ignat");
Console.WriteLine("called directly first name : " + x.FirstName);
Console.WriteLine("called via enum of prop first name : " + x.GetPropValue(ePerson_Properties.FirstName));
Console.WriteLine("called get property :" + x.GetPropValue(ePerson_Properties.Name));
Console.WriteLine("this will throw error because Name has not set ");
try
{
x.SetPropValue(ePerson_Properties.Name, "asd");
}
catch (Exception)
{
Console.WriteLine("this is good!");
}
Console.ReadLine();
This is the use of RSCG_Templating in Person.cs
using RSCG_TemplatingCommon;
namespace RSCG_TemplatingDemo;
[IGenerateDataFromClass("ClassTypeName")]
[IGenerateDataFromClass("ClassPropByName")]
public partial class Person
{
public string Name { get { return FullName(" "); } }
public string? FirstName { get; set; }
public string? LastName { get; set; }
public string FullName(string separator = " ")
{
return FirstName + separator + LastName;
}
public void DisplayNameOnConsole()
{
Console.WriteLine(FullName());
}
public async Task<string> GetName()
{
await Task.Delay(1000);
return FirstName ?? "";
}
public Task<string> GetFullName()
{
return Task.FromResult(FullName());
}
public Task SaveId(int id)
{
if (id < 0)
{
throw new ArgumentException("this is an error because is <0 ");
}
return Task.CompletedTask;
}
}
This is the use of RSCG_Templating in ClassPropByName.txt
//autogenerated by RSCG_Templating version {{data.Version}} from file {{fileName}}
namespace {{data.nameSpace}} {
public enum e{{data.className}}_Properties {
None = 0,
{{ for prop in data.properties }}
{{prop.PropertyName}},
{{ end }}
}
partial class {{data.className}} {
public object GetPropValue(e{{data.className}}_Properties prop){
switch(prop){
{{ for prop in data.properties }}
case e{{data.className}}_Properties.{{prop.PropertyName}}:
{{ if prop.CanCallGetMethod }}
return this.{{prop.PropertyName}};
{{ else }}
throw new NotImplementedException();
{{ end}}
{{ end }}
default:
throw new NotImplementedException();
}
}
public void SetPropValue<T>(e{{data.className}}_Properties prop , T value){
switch(prop){
{{ for prop in data.properties }}
case e{{data.className}}_Properties.{{prop.PropertyName}}:
{{ if prop.CanCallSetMethod }}
this.{{prop.PropertyName}} = ({{prop.PropertyType}})(dynamic)value;
break;
{{ else }}
throw new NotImplementedException();
{{ end}}
{{ end }}
default:
throw new NotImplementedException();
}
}
}//end class
}//end namespace
This is the use of RSCG_Templating in ClassTypeName.txt
//autogenerated by RSCG_Templating version {{data.Version}} from file {{fileName}}
namespace {{data.nameSpace}} {
partial class {{data.className}} {
public string MyTypeName = "{{data.nameSpace}}.{{data.className}}";
}//end class
}//end namespace
Generated Files
Those are taken from $(BaseIntermediateOutputPath)\GX
- RSCG_TemplatingDemo.Person.ClassPropByName.cs
- RSCG_TemplatingDemo.Person.ClassTypeName.cs
//autogenerated by RSCG_Templating version 2023.1022.1748.0 from file Microsoft.CodeAnalysis.AdditionalTextFile
namespace RSCG_TemplatingDemo {
public enum ePerson_Properties {
None = 0,
Name,
FirstName,
LastName,
}
partial class Person {
public object GetPropValue(ePerson_Properties prop){
switch(prop){
case ePerson_Properties.Name:
return this.Name;
case ePerson_Properties.FirstName:
return this.FirstName;
case ePerson_Properties.LastName:
return this.LastName;
default:
throw new NotImplementedException();
}
}
public void SetPropValue<T>(ePerson_Properties prop , T value){
switch(prop){
case ePerson_Properties.Name:
throw new NotImplementedException();
case ePerson_Properties.FirstName:
this.FirstName = (string?)(dynamic)value;
break;
case ePerson_Properties.LastName:
this.LastName = (string?)(dynamic)value;
break;
default:
throw new NotImplementedException();
}
}
}//end class
}//end namespace
//autogenerated by RSCG_Templating version 2023.1022.1748.0 from file Microsoft.CodeAnalysis.AdditionalTextFile
namespace RSCG_TemplatingDemo {
partial class Person {
public string MyTypeName = "RSCG_TemplatingDemo.Person";
}//end class
}//end namespace
Usefull
Download Example (.NET C# )
Share RSCG_Templating
https://ignatandrei.github.io/RSCG_Examples/v2/docs/RSCG_Templating