Skip to content

Instantly share code, notes, and snippets.

@Chandankkrr
Last active June 24, 2021 01:21
Show Gist options
  • Save Chandankkrr/746edce056ee5ba7605a755d17c9d2a0 to your computer and use it in GitHub Desktop.
Save Chandankkrr/746edce056ee5ba7605a755d17c9d2a0 to your computer and use it in GitHub Desktop.
MediatR Source Generator
using System.Diagnostics;
using System.Linq;
using System.Text;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
namespace MediatorGenerator
{
[Generator]
public sealed class SourceGenerator : ISourceGenerator
{
public void Initialize(GeneratorInitializationContext context)
{
#if DEBUG
if (!Debugger.IsAttached)
{
Debugger.Launch();
}
#endif
}
public void Execute(GeneratorExecutionContext context)
{
var sourceBuilder = new StringBuilder(@"
using System;
namespace HelloWorldGenerated
{
public static class HelloWorld
{
public static void SayHello()
{
Console.WriteLine(""Hello from generated code!"");
Console.WriteLine(""The following syntax trees existed in the compilation that created this program:"");
");
// using the context, get a list of syntax trees in the users compilation
var syntaxTrees = context.Compilation.SyntaxTrees;
var commands = syntaxTrees.Where(x => x.GetText().ToString().Contains("Command"));
var commandSourceBuilder = new StringBuilder();
foreach (var command in commands)
{
var usingDirectives = command.GetRoot().DescendantNodes().OfType<UsingDirectiveSyntax>();
var usingDirectivesAsText = string.Join("\r\n", usingDirectives);
commandSourceBuilder.Append(usingDirectivesAsText);
var classDeclarationSyntax =
command.GetRoot().DescendantNodes().OfType<ClassDeclarationSyntax>().First();
var className = classDeclarationSyntax.Identifier.ToString();
var generatedClassName = $"{className}Handler";
var splitClass = classDeclarationSyntax.ToString().Split(new[] {'{'}, 2);
commandSourceBuilder.Append($@"
namespace GeneratedCommandHandler
{{
public class {generatedClassName} : IRequestHandler<{className}, ApplicationUserResult>
{{
public {generatedClassName}()
{{
}}
public async Task<ApplicationUserResult> Handle({className} request, CancellationToken cancellationToken)
{{
}}
}}
}}
");
}
// add the filepath of each tree to the class we're building
// foreach (SyntaxTree tree in syntaxTrees)
// {
// sourceBuilder.AppendLine($@"Console.WriteLine(@"" - {tree.FilePath}"");");
// }
//
// finish creating the source to inject
// sourceBuilder.Append(@"
// }
// }
// }");
// inject the created source into the users compilation
context.AddSource("helloWorldGenerator", SourceText.From(commandSourceBuilder.ToString(), Encoding.UTF8));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment