Gobie DevLog 3 - Simple C# Source Generation
In the last post about Gobie we looked at Class and Field templates along with formatting options. Today we can look at File templates.
Updates
Released in v0.4.0-alpha:
- Added file templates.
Current Status
Just to be clear, this is currently not usable for anything other than a demo. Additionally, it isn’t stable.
Demo
File templates, the ability to define that a separate file (and probably class) should be generated, is the third of four core features I wanted to include in Gobie on initial release. The usage for this pattern which is clearest to me, is to generate a dedicate log class for your existing class. Below we will look at a simple example of this pattern. In fact it is simple enough we could rely on inheritance and not generation for the bulk of the log class. In a future post we will look at a more complex example.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
[GobieGeneratorName("LoggedClass")]
public sealed class LoggedClassGenBase : GobieClassGenerator
{
[GobieTemplate]
private const string LogString = @"
private readonly System.Collections.Generic.List<{{ClassName}}Log> logs = new();
/// <summary> Standardized log entries for <see cref=""{{ClassName}}"">. </summary>
public System.Collections.Generic.IEnumerable<{{ClassName}}Log> Logs => logs.AsReadOnly();";
[GobieFileTemplate("Log")]
private const string KeyString = @"
using System;
namespace {{ClassNamespace}};
public sealed class {{ClassName}}Log
{
public int Id { get; set; }
public {{ClassName}} Parent {get; set;}
public DateTime Timestamp {get; set;}
public string LogMessage {get; set;}
}
";
}
This is the first time we need to have multiple templates in a generator.
GobieTemplate
is defining the code we will add to the existing partial class.GobieFileTemplate
defines a new file and new class we will generate. In the case of theAuthor
class, this will generate anAuthorLog
class.
We can apply the template as shown below.
1
2
3
4
5
6
7
namespace Models
{
[LoggedClass]
public partial class Author
{
}
}
And we generate the two files below:
1
2
3
4
5
6
7
8
9
10
// File: Author_LoggedClassAttribute.g.cs
namespace Models
{
public partial class Author
{
private readonly System.Collections.Generic.List<AuthorLog> logs = new();
/// <summary> Standardized log entries for <see cref = "Author">. </summary>
public System.Collections.Generic.IEnumerable<AuthorLog> Logs => logs.AsReadOnly();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// File: Author_LoggedClassAttribute_Log.g.cs
using System;
namespace Models;
public sealed class AuthorLog
{
public int Id { get; set; }
public Author Parent { get; set; }
public DateTime Timestamp { get; set; }
public string LogMessage { get; set; }
}
Feedback
I am very interested in feedback. Feel free to drop a note in the comments here or open an issue with your thoughts in the project repo
Leave a Comment
Your email address will not be published. Required fields are marked *