After my post first post on: Code Generation I decided to go a bit further, so today we’ll Create a class with .NET Core and Roslyn and write the output to the console.
Let’s see:
Create the application
Open a command prompt and run
1 md roslyn.create.class
2 cd roslyn.create.class
3 dotnet new
4 dotnet restore
5 code .
Replace the contents of project.json
Replace the contents on project.json file in order to include the references to: Microsoft.CodeAnalysis.CSharp and **Microsoft.CodeAnalysis.Compilers **
1{
2 "version": "1.0.0-*",
3 "buildOptions": {
4 "debugType": "portable",
5 "emitEntryPoint": true
6 },
7 "dependencies": {
8 "Microsoft.CodeAnalysis.CSharp": "2.0.0-rc4",
9 "Microsoft.CodeAnalysis.Compilers": "2.0.0-rc4"
10 },
11 "frameworks": {
12 "netcoreapp1.1": {
13 "dependencies": {
14 "Microsoft.NETCore.App": {
15 "type": "platform",
16 "version": "1.1.0"
17 }
18 },
19 "imports": "dnxcore50"
20 }
21 }
22}
Replace the contents of Program.cs
The CreateClass method is where the magic occurs. Each relevant line is explained to help you understand each step.
1using System;
2using Microsoft.CodeAnalysis;
3using Microsoft.CodeAnalysis.CSharp;
4
5namespace Roslyn.CodeGeneration
6{
7 public class Program
8 {
9 public static void Main(string[] args)
10 {
11 // Create a class
12 CreateClass();
13
14 // Wait to exit.
15 Console.Read();
16 }
17
18 /// <summary>
19 /// Create a class from scratch.
20 /// </summary>
21 static void CreateClass()
22 {
23 // Create a namespace: (namespace CodeGenerationSample)
24 var @namespace = SyntaxFactory.NamespaceDeclaration(SyntaxFactory.ParseName("CodeGenerationSample")).NormalizeWhitespace();
25
26 // Add System using statement: (using System)
27 @namespace = @namespace.AddUsings(SyntaxFactory.UsingDirective(SyntaxFactory.ParseName("System")));
28
29 // Create a class: (class Order)
30 var classDeclaration = SyntaxFactory.ClassDeclaration("Order");
31
32 // Add the public modifier: (public class Order)
33 classDeclaration = classDeclaration.AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword));
34
35 // Inherit BaseEntity<T> and implement IHaveIdentity: (public class Order : BaseEntity<T>, IHaveIdentity)
36 classDeclaration = classDeclaration.AddBaseListTypes(
37 SyntaxFactory.SimpleBaseType(SyntaxFactory.ParseTypeName("BaseEntity<Order>")),
38 SyntaxFactory.SimpleBaseType(SyntaxFactory.ParseTypeName("IHaveIdentity")));
39
40 // Create a string variable: (bool canceled;)
41 var variableDeclaration = SyntaxFactory.VariableDeclaration(SyntaxFactory.ParseTypeName("bool"))
42 .AddVariables(SyntaxFactory.VariableDeclarator("canceled"));
43
44 // Create a field declaration: (private bool canceled;)
45 var fieldDeclaration = SyntaxFactory.FieldDeclaration(variableDeclaration)
46 .AddModifiers(SyntaxFactory.Token(SyntaxKind.PrivateKeyword));
47
48 // Create a Property: (public int Quantity { get; set; })
49 var propertyDeclaration = SyntaxFactory.PropertyDeclaration(SyntaxFactory.ParseTypeName("int"), "Quantity")
50 .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword))
51 .AddAccessorListAccessors(
52 SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration).WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)),
53 SyntaxFactory.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration).WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)));
54
55 // Create a stament with the body of a method.
56 var syntax = SyntaxFactory.ParseStatement("canceled = true;");
57
58 // Create a method
59 var methodDeclaration = SyntaxFactory.MethodDeclaration(SyntaxFactory.ParseTypeName("void"), "MarkAsCanceled")
60 .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword))
61 .WithBody(SyntaxFactory.Block(syntax));
62
63 // Add the field, the property and method to the class.
64 classDeclaration = classDeclaration.AddMembers(fieldDeclaration, propertyDeclaration, methodDeclaration);
65
66 // Add the class to the namespace.
67 @namespace = @namespace.AddMembers(classDeclaration);
68
69 // Normalize and get code as string.
70 var code = @namespace
71 .NormalizeWhitespace()
72 .ToFullString();
73
74 // Output new code to the console.
75 Console.WriteLine(code);
76 }
77 }
78}
Run the application
1 dotnet restore
2 dotnet run
The output should read:
1namespace CodeGenerationSample
2{
3 using System;
4
5 public class Order : BaseEntity<Order>, IHaveIdentity
6 {
7 private bool canceled;
8 public int Quantity
9 {
10 get;
11 set;
12 }
13
14 public void MarkAsCanceled()
15 {
16 canceled = true;
17 }
18 }
19}
Get a copy of the code here: https://github.com/cmendible/dotnetcore.samples/tree/main/roslyn.create.class
Hope it helps!
Comments