Skip to content

Instantly share code, notes, and snippets.

@mirmostafa
Created August 27, 2021 16:33
Show Gist options
  • Save mirmostafa/58870c4fcb03faeb1b8ab5c9db131653 to your computer and use it in GitHub Desktop.
Save mirmostafa/58870c4fcb03faeb1b8ab5c9db131653 to your computer and use it in GitHub Desktop.
C# Source Generator Template
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<LangVersion>preview</LangVersion>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Library\Library.csproj" />
<ProjectReference Include="..\..\SourceGeneratorContracts\SourceGeneratorContracts.csproj" />
<ProjectReference Include="..\..\SourceGenerator\SourceGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
</ItemGroup>
</Project>
using System.Diagnostics;
using System.Linq;
using System.Text;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
namespace Library.SourceGenerator;
[Generator]
public class ModelDtoGenerator : ISourceGenerator
{
public void Execute(GeneratorExecutionContext context)
{
var syntaxTrees = context.Compilation.SyntaxTrees;
foreach (var syntaxTree in syntaxTrees)
{
var generateDtoClasses = syntaxTree.GetRoot().DescendantNodes().OfType<TypeDeclarationSyntax>()
.Where(x => x.AttributeLists.Any(xx => xx.ToString().StartsWith("[GenerateDto")));
foreach (var generateDtoClass in generateDtoClasses)
{
var usingDirectives = syntaxTree.GetRoot().DescendantNodes().OfType<UsingDirectiveSyntax>();
var usingDirectivesAsText = string.Join("\r\n", usingDirectives);
var sourceBuilder = new StringBuilder(usingDirectivesAsText);
var className = generateDtoClass.Identifier.ToString();
var dtoClassName = $"{className}Dto";
var splitClass = generateDtoClass.ToString().Split(new[] { '{' }, 2);
sourceBuilder.Append($@"
namespace Models
{{
public class {dtoClassName}
{{
");
sourceBuilder.AppendLine(splitClass[1].Replace(className, dtoClassName));
sourceBuilder.AppendLine("}");
context.AddSource($"{dtoClassName}.Generated.cs", SourceText.From(sourceBuilder.ToString(), Encoding.UTF8));
Debug.WriteLine($"{dtoClassName} generated.");
}
}
}
public void Initialize(GeneratorInitializationContext context)
{
//#if DEBUG
// if (!Debugger.IsAttached)
// {
// Debugger.Launch();
// }
//#endif
}
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Nullable>enable</Nullable>
<IsRoslynComponent>true</IsRoslynComponent>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>preview</LangVersion>
<RootNamespace>Library.$(MSBuildProjectName.Replace(" ", "_"))</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="3.11.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.11.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.11.0" />
<!--<PackageReference Include="System.CodeDom" Version="5.0.0" />-->
</ItemGroup>
</Project>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment