Sundew.Generator
3.1.17-u20231126-092633-ci
See the version list below for details.
dotnet add package Sundew.Generator --version 3.1.17-u20231126-092633-ci
NuGet\Install-Package Sundew.Generator -Version 3.1.17-u20231126-092633-ci
<PackageReference Include="Sundew.Generator" Version="3.1.17-u20231126-092633-ci" />
paket add Sundew.Generator --version 3.1.17-u20231126-092633-ci
#r "nuget: Sundew.Generator, 3.1.17-u20231126-092633-ci"
// Install Sundew.Generator as a Cake Addin #addin nuget:?package=Sundew.Generator&version=3.1.17-u20231126-092633-ci&prerelease // Install Sundew.Generator as a Cake Tool #tool nuget:?package=Sundew.Generator&version=3.1.17-u20231126-092633-ci&prerelease
Sundew.Generator
Sundew.Generator is code generator aiming to provide an alternative or replacement for T4 templates.
Generators are simple C# console applications that execute themselves after being built.
The concept separates generators from models and output, meaning it is possible to have several generators operate on the same input (models) and have the result placed in one or more outputs (writers).
Getting started
- Create a new project (Console application).
- Add the Sundew.Generator or Sundew.Generator.Code NuGet package.
- Implement a generator
- Setup
- Implement the main method, something like this:
public static Task Main()
{
return GeneratorFacade.RunAsync(new MySetupsFactory());
}
- Build (and it will run)
<a id="implement_a_generator"></a>Implementing a generator
A generator can be added by implementing the generic Sundew.Generator.IGenerator<in TSetup, in TGeneratorSetup, in TTarget, in TModel, TRun, out TOutput>
interface.
The interface take quite a few generic parameters, which the developer can decide and requires the implementation of two methods.
Prepare must return a number IRuns, which will cause the Generate method to be called for each run. Typically prepare will return a single run.
Generate can output anything as long as the writer accepts the output, but typically this would be text, such as TextOutput.
Sundew.Generator does not support any form of preprocessed text templates like T4. For readability string interpolation combined with methods may be used.
public interface IGenerator<in TSetup, in TGeneratorSetup, in TTarget, in TModel, TRun, out TOutput> : IGenerator
where TTarget : ITarget
where TRun : IRun
{
IReadOnlyList<TRun> Prepare(TSetup setup, TGeneratorSetup generatorSetup, TTarget target, TModel model, string modelPath);
TOutput Generate(TSetup setup, TGeneratorSetup generatorSetup, TTarget target, TModel model, TRun run, long index);
}
Generator Example
<a id="setup"></a>Setup
The setup is used to configure models, generators and writers.
The Sundew.Generator.Setup
allows setting a ModelSetup, one of more GeneratorSetups and one or more WriterSetups.
ModelSetup
A model setup allows to specify a ModelProvider and the ModelType with the Sundew.Generator.Input.ModelSetup
class. If neither a ModelProvider or ModelType is specified an Sundew.Generator.ModelProviders.EmptyModelProvider<object>
will be used.
If only a model type is specified Sundew.Generator.ModelProviders.JsonModelProvider<TModel>
will be used.
Model Providers
Sundew.Generator ships with three model providers out the box:
Sundew.Generator.ModelProviders.XmlModelProvider<TModel>
Sundew.Generator.ModelProviders.JsonModelProvider<TModel>
Sundew.Generator.ModelProviders.EmptyModelProvider<TModel>
XmlModelProvider
and JsonModelProvider
can use an Sundew.Generator.Input.FolderModelSetup
to specify folder and file pattern to search for model files.
EmptyModelProvider
provides a single model through its default constructor.
Implementing a model provider
To implement a model provider use the Sundew.Generator.Input.IModelProvider<in TSetup, in TModelSetup, TModel>
interface.
The interface consists of a single async method that results a list of models. GetModelsAsync takes two parameters, the setup with which the generation was setup and a model setup.
public interface IModelProvider<in TSetup, in TModelSetup, TModel> : IModelProvider
where TModelSetup : class
where TModel : class
{
Task<IReadOnlyList<IModelInfo<TModel>>> GetModelsAsync(TSetup setup, TModelSetup modelSetup);
}
Model Provider Example
GeneratorSetups
Sundew.Generator.GeneratorSetup
specify which generators to run and also allow to add generator specific settings.
Additionally, they may also specify any number of WriterSetups that will only be used for this particular generator and a boolean indicating whether the global WriterSetups should skip the generator (default false).
WriterSetups
Writer setups help configure what happens with a generator's output. Sundew.Generator.Output.WriterSetup
provides a target (any string) and a writer.
There is also the Sundew.Generator.Output.FileWriterSetup
which can be used to specify a filename suffix and extension.
Writers
Sundew.Generator.Writers.TextFileWriter
writes text output of each run to a file and uses theWriterSetup.Target
to specify the folder to write to.Sundew.Generator.Code.ProjectTextFileWriter
is available in the Sundew.Generator.Code NuGet package and can be used with the providedSundew.Generator.Code.CodeSetup
to generate C# code. It expects theWriterSetup.Target
to be csproj or vbproj to determine the default namespace and root folder to store generated files.
Implementing a writer
Similar to generators and model providers, a custom writer can be added be implementing the Sundew.Generator.Output.IWriter<in TWriterSetup, TTarget, in TRun, in TOutput>
interface.
This is by far the most complex interface because it can manage the output of a generator.
- GetTargetAsync runs in the very beginning of the generation process and provides a target for the generators prepare method. For example the
Sundew.Generator.Writers.TextFileWriter
builds the target folder path. - PrepareTargetAsync runs after the generation process.
- ApplyContentToTargetAsync runs for each of the generated outputs of the generator and allows to gather the output or persist it.
- CompleteTargetAsync runs once as a last step in the generation process and may be used to persist gathered output if necessary.
public interface IWriter<in TWriterSetup, TTarget, in TRun, in TOutput> : IWriter
where TWriterSetup : IWriterSetup
where TTarget : ITarget
where TRun : IRun
{
Task<TTarget> GetTargetAsync(TWriterSetup writerSetup);
Task PrepareTargetAsync(TTarget target, TWriterSetup writerSetup);
Task<string> ApplyContentToTargetAsync(TTarget target, TRun run, TWriterSetup writerSetup, TOutput output);
Task CompleteTargetAsync(ITargetCompletionTracker targetCompletionTracker);
}
Writer Example
Additional info
Including generated code in a build
With SDK-style projects files can be included with a wildcard an ItemGroup, while the WriterSetup can be configured to output the generated files to a .generated folder.
<ItemGroup>
<Compile Include=".generated\**\*.cs" />
</ItemGroup>
It might also be suitable to add the .generated folder to .gitignore to avoid checking in generated files.
.generated/
Configuring build order
In Visual Studio the Build Dependencies feature can be used to ensure that the generator runs before any consuming project without creating a project reference.
Right click the solution in Solution Explorer - Build Dependencies - Build Dependencies to set up the build order.
Number of runs
The number times each generator runs is determined the following way:
#WriterSetups * #Models * #Runs
Json Serialized Setups
Sundew.Generator support using json files to setup up the generator.
Use the RunAsync overload on the GeneratorFacade and specify the directory and file pattern to search for setup files.
GeneratorFacade.RunAsync(string directory, string pattern, GeneratorOptions generatorOptions = null)
In a json setup file a "Type"
property may be specified with the fully qualified name to tell the deserializer, which type to use for Setup, GeneratorSetup, ModelSetup and WriterSetup.
License:
MIT
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Newtonsoft.Json (>= 13.0.3)
- Sundew.Base.Collections (>= 11.0.1)
- Sundew.Base.Text (>= 11.0.1)
- Sundew.Base.Threading (>= 11.0.1)
- Sundew.IO (>= 1.0.0)
- System.Threading.Tasks.Parallel (>= 4.3.0)
NuGet packages (3)
Showing the top 3 NuGet packages that depend on Sundew.Generator:
Package | Downloads |
---|---|
Sundew.Generator.Code
Sundew.Generator is code generator aiming to provide an alternative or replacement for T4 templates. |
|
Sundew.Generator.CommandLine
Console application for generation. |
|
Sundew.Generator.CodeAnalysis.MSBuildWorkspace
Generation library |
GitHub repositories
This package is not used by any popular GitHub repositories.
3.0 - Changed to .NET Standard 2.0