Skip to content

Commit 514f6e3

Browse files
committed
Moving sample source generator to /Samples, as well as the other source generator that generates POCOs (was in another repo)
1 parent 5a3cb13 commit 514f6e3

27 files changed

+56331
-132
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -342,3 +342,5 @@ ASALocalRun/
342342
!src/Tools/Tests/Templates/*.generated.cs
343343

344344
/src/Models/CodegenCS.Models.NSwagAdapter/CodegenCS.Models.NSwagAdapter.xml
345+
dotnet-tools.json
346+
/Samples/PrebuildEvent/DapperExtensionPocos.dll

README.md

+33-29
Original file line numberDiff line numberDiff line change
@@ -32,33 +32,35 @@ Our templates use a [Hybrid model](https://github.com/Drizin/CodegenCS/tree/mast
3232

3333
To sum our hybrid model provides the best of both worlds: you can write templates using your favorite language (C#), in your favorite IDE (Visual Studio) with full **debugging** capabilities - and you can **leverage the power of .NET** and any **.NET library** (think LINQ, Dapper, Newtonsoft, Swashbuckle, RestSharp, Humanizer, etc.)
3434

35-
## Entrypoint and subtemplates
35+
## Template Entrypoint
3636

37-
Templates are C# programs so they need an entrypoint (`Main()` or `TemplateMain()`).
37+
Templates are C# programs so they should have an entrypoint method (named `Main()` or `TemplateMain()`).
3838

39-
Entry-points can be markup-based (they just have to return an interpolated string):
39+
Methods can be "markup-based" which means that they just return an interpolated string:
4040

4141
```cs
4242
class MyTemplate
4343
{
4444
FormattableString Main() => $"My first template";
4545
}
4646
```
47-
... or they can be programmatic:
47+
Or they can be programmatic:
4848

4949
```cs
5050
class MyTemplate
5151
{
5252
void Main(ICodegenOutputFile writer)
5353
{
54-
writer.WriteLine($"My first template");
54+
writer.Write($"My first template");
5555
}
5656
}
5757
```
5858

5959
## Subtemplates (aka "partials")
6060

61-
In regular C# string interpolation you can only interpolate types that can be directly converted to string (`string`, `FormattableString`, `int`, `DateTime`, etc.). In our hybrid model you can interpolate many other types including delegates (methods) so it's very easy to "embed" a subtemplate (a different method) right within an interpolated string.
61+
In a programmatic method it's pretty obvious that you can just invoke other methods to break down a template into smaller (and more organized blocks), but when you have a markup-based block (i.e. a large string) it's not so obvious how you can include a "subtemplate":
62+
63+
In regular C# string interpolation we can only interpolate types that can be directly converted to string (`string`, `FormattableString`, `int`, `DateTime`, etc.), but in our magic TextWriter allows interpolating many other types including delegates (methods) so it's very easy to "embed" a subtemplate (a different method) right within an interpolated string.
6264

6365
In the example below template starts with a markup entry-point and then it "escapes" from the markup and switches to a programmatic subtemplate (another method that might have more complex logic):
6466

@@ -87,6 +89,10 @@ class MyTemplate
8789
}
8890
```
8991

92+
(`WriteClass` method will get the `ICodegenOutputFile` parameter automatically injected, as explained later).
93+
94+
Switching back and forth between programmatic-mode (C# methods) or markup mode (large C# strings) is what enables our hybrid model.
95+
9096
## Indentation Control
9197

9298
Our clever [Indent Control](https://github.com/Drizin/CodegenCS/tree/master/docs/Indent-Control.md) automatically captures the current indent (whatever number of spaces or tabs you have in current line) and will preserve it when you interpolate a large object (multiline) or when you interpolate a subtemplate.
@@ -95,37 +101,29 @@ Generating code with the correct indentation (even if there are multiple nested
95101

96102
Explicit indent control is also supported.
97103

104+
98105
## Command-line Tool (dotnet-codegencs)
99106

100-
[dotnet-codegencs](https://github.com/Drizin/CodegenCS/tree/master/src/Tools/dotnet-codegencs/) is a cross-platform .NET tool (command-line tool) that can be used to download, **build**, and **run templates**.
101-
It can also be used to extract models (reverse engineer schema) from existing databases.
102-
In other words this is our **"batteries-included"** tool, and probably the best place to get started.
103-
It's available for Windows/Linux/MacOS.
107+
[dotnet-codegencs](https://github.com/Drizin/CodegenCS/tree/master/src/Tools/dotnet-codegencs/) is a cross-platform .NET tool (command-line tool).
108+
It's available for Windows/Linux/MacOS.
109+
110+
Besides running templates, it can also be used to extract models from existing databases (**reverse engineer db schema**), or download our our [sample templates](https://github.com/CodegenCS/Templates).
111+
So if you want to quickly start generating code (e.g. based on your database) this is our **"batteries-included"** tool.
112+
113+
You can run it manually or you can automate into your build pipeline. See [this example](/Samples/PrebuildEvent/RunTemplates.ps1) of a prebuild script that will install dotnet-codegencs, refresh a database schema, and run a template that generates POCOs.
104114

105115
## Visual Studio Extension
106116

107-
Our [Visual Studio Extension](https://github.com/Drizin/CodegenCS/tree/master/src/VisualStudio/) allows **building and running templates** directly from Visual Studio.
108-
Output files are automatically added to the project (nested under the template item), so it's easy to use (but it doesn't have all features available in `dotnet-codegencs`).
117+
Our [Visual Studio Extension](https://github.com/Drizin/CodegenCS/tree/master/src/VisualStudio/) allows running templates directly from Visual Studio.
109118
It's available for [Visual Studio 2022](https://marketplace.visualstudio.com/items?itemName=Drizin.CodegenCS) or [Visual Studio 2019/2017](https://marketplace.visualstudio.com/items?itemName=Drizin.CodegenCS-Compatibility).
110119

120+
Output files are automatically added to the project (nested under the template item), so it's easy to use (but it doesn't have all features available in `dotnet-codegencs`).
121+
111122
## Roslyn Source Generator
112123

113-
Our [Source Generator](https://nuget.org/packages/CodegenCS.SourceGenerator) allows running templates on-the-fly during compilation.
124+
Our [Source Generator](https://github.com/Drizin/CodegenCS/tree/master/src/SourceGenerator/) (nuget [here](https://nuget.org/packages/CodegenCS.SourceGenerator)) allows running templates on-the-fly during compilation.
114125
It's possible to render physical files on disk or just render in-memory (no need to add to source-control or put into ignore lists).
115126

116-
How to use:
117-
1. Install nuget CodegenCS.SourceGenerator to your project
118-
2. Add this to your project
119-
```
120-
<ItemGroup>
121-
<CompilerVisibleItemMetadata Include="AdditionalFiles" MetadataName="CodegenCSOutput" />
122-
<AdditionalFiles Include="Template.csx" CodegenCSOutput="Memory" />
123-
<!-- Use "Memory" or "File", where "File" will save the output files to disk -->
124-
<!-- you can include as many templates as you want -->
125-
</ItemGroup>
126-
```
127-
3. If you want to augment on existing classes (using Roslyn Syntax Tree), just inject GeneratorExecutionContext (see [Template3.csx](/src/SourceGenerator/SampleProjectWithSourceGenerator/Template3.csx) example).
128-
129127
## Important Classes
130128

131129
Before explaining more features it's important to first learn about 3 important classes:
@@ -1139,6 +1137,7 @@ See example in
11391137
- [CodegenTextWriter documentation](https://github.com/Drizin/CodegenCS/tree/master/docs/CodegenTextWriter.md)
11401138
- To start using the command-line tool, check out [dotnet-codegencs Quickstart](https://github.com/Drizin/CodegenCS/tree/master/src/Tools/dotnet-codegencs#quickstart)
11411139
- To start using the Visual Studio Extension, check out [Visual Studio Extension Quickstart](https://github.com/Drizin/CodegenCS/tree/master/src/VisualStudio#quickstart)
1140+
- To start using the Source Generator, check out [Roslyn Source Generator Quickstart](https://github.com/Drizin/CodegenCS/tree/master/src/SourceGenerator#quickstart)
11421141
- To generate code based on a database, check out [DbSchema Quickstart](https://github.com/Drizin/CodegenCS/tree/master/src/Models/CodegenCS.Models.DbSchema#quickstart)
11431142
- To generate code based on a REST API, check out [NSwagAdapter Quickstart](https://github.com/Drizin/CodegenCS/tree/master/src/Models/CodegenCS.Models.NSwagAdapter#quickstart)
11441143
- Our [Templates repository (https://github.com/CodegenCS/Templates)](https://github.com/CodegenCS/Templates) contains some **sample fully-functional templates** that you can use, customize, or use as a reference for building your own templates.
@@ -1196,10 +1195,15 @@ ctx.SaveToFolder(@"C:\MyProject\");
11961195
Check out [CodegenCS vs T4 Templates](https://github.com/Drizin/CodegenCS/tree/master/docs/Comparison-T4.md)
11971196
(Spoiler: CodegenCS is much much better)
11981197
1199-
## How does CodegenCS compare to Roslyn?
1198+
## How does CodegenCS compare to Roslyn Source Generators?
1199+
1200+
Source Generators are only required when you're building code based on existing code.
1201+
CodegenCS has a Source Generator plugin that can be used to invoke templates, and those templates will also have access to `GeneratorExecutionContext` (to read the syntax trees) - so you don't have to write your own Source Generator (which is not an easy task).
1202+
1203+
But if you're not building code based on existing code (e.g. if you're generating based on a database or a json file) then you don't need a Source Generator - you can just use our command-line tool `dotnet-codegencs` to run our templates from your prebuild scripts.
1204+
1205+
For more details check out [CodegenCS vs Roslyn Source Generators](https://github.com/Drizin/CodegenCS/tree/master/docs/Comparison-Roslyn.md)
12001206
1201-
Check out [CodegenCS vs Roslyn](https://github.com/Drizin/CodegenCS/tree/master/docs/Comparison-Roslyn.md)
1202-
(Spoiler: That's not an apples-to-apples comparison. Roslyn should be used to analyze compilation syntax-trees and eventually generate code **based** on that syntax tree - but generating code using syntax-trees is painful and nonsense. CodegenCS was created for generating human-readable code and let the hard-work of syntax trees be done by a compiler).
12031207
12041208
## Why yet another Code Generator? Why not T4, Liquid, Razor, etc?
12051209

0 commit comments

Comments
 (0)