Skip to content

Instantly share code, notes, and snippets.

@rkttu
Created June 11, 2024 04:26
Show Gist options
  • Save rkttu/56c8a96b48a3534a55a671bb8774931f to your computer and use it in GitHub Desktop.
Save rkttu/56c8a96b48a3534a55a671bb8774931f to your computer and use it in GitHub Desktop.
Sample code to use Mono.TextTemplating in-memory without file input/output
// This sample code requires Mono.TextTemplating.Roslyn >= 2.3.1 nuget package
using System;
using Microsoft.VisualStudio.TextTemplating;
using Mono.TextTemplating;
using System.CodeDom.Compiler;
using System.Threading;
using System.Threading.Tasks;
internal static class Program
{
private static async Task Main(string[] args)
{
var templateContent = $$"""
<#@ template language="C#" #>
namespace GeneratedNamespace
{
public class GeneratedClass
{
<# if (!(bool)Session["machineOrUser"]) { #>
public string UserSid { get; set; } = "<#= TemplatingExtensions.TestVariable #>";
<# } #>
public RegistryValueOptions RegistryValueOptions { get; set; } = RegistryValueOptions.None;
public RegistryView RegistryView { get; set; } = RegistryView.Default;
}
}
""";
var result = await templateContent.ProcessTemplateAsync(
sessionConfigurator: s =>
{
s["machineOrUser"] = false;
},
templateSettingsConfigurator: s =>
{
s.Assemblies.Add(typeof(TemplatingExtensions).Assembly.FullName);
s.InternalVisibility = true;
}).ConfigureAwait(false);
if (result.CompileSucceed)
await Console.Out.WriteLineAsync(result.Value.AsMemory()).ConfigureAwait(false);
else
await Console.Error.WriteLineAsync("Text templating/compilation failed.".AsMemory()).ConfigureAwait(false);
}
}
public static class TemplatingExtensions
{
public static string TestVariable = "Hello, World!";
public static async Task<TemplatingResult> ProcessTemplateAsync(
this string templateContent,
bool useInProcessCompiler = true,
Action<ITextTemplatingSession> sessionConfigurator = default,
Action<TemplateSettings> templateSettingsConfigurator = default,
CancellationToken cancellationToken = default)
{
var generator = new TemplateGenerator();
if (useInProcessCompiler)
generator.UseInProcessCompiler();
var session = generator.GetOrCreateSession();
if (sessionConfigurator != null)
sessionConfigurator.Invoke(session);
var parsedTemplate = generator.ParseTemplate(default, templateContent);
var templateSettings = TemplatingEngine.GetSettings(generator, parsedTemplate);
if (templateSettingsConfigurator != null)
templateSettingsConfigurator.Invoke(templateSettings);
var engine = new TemplatingEngine();
var compilerResult = await engine.CompileTemplateAsync(
parsedTemplate, null, generator,
templateSettings, cancellationToken).ConfigureAwait(false);
return new TemplatingResult(
generator.Errors,
compilerResult.HasValue,
compilerResult?.references,
compilerResult?.template?.Process());
}
}
public sealed class TemplatingResult
{
public TemplatingResult(
CompilerErrorCollection errors,
bool compileSucceed,
string[] references,
string value)
{
Errors = errors;
CompileSucceed = compileSucceed;
References = references;
Value = value;
}
public CompilerErrorCollection Errors { get; } = null;
public bool CompileSucceed { get; } = false;
public string[] References { get; } = new string[] { };
public string Value { get; } = null;
public override string ToString() => Value;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment