Skip to content

uml4net.CodeGenerator.project

samatstarion edited this page Jan 2, 2025 · 1 revision

Introduction

The uml4net.CodeGenerator project contains various code generators that are run from the associated uml4net.CodeGenerator.Tests project. This project, as opposed to the other projects in the solution, is not distributed as a nuget as it is very specific for uml4net and not designed for re-use. Although the patters used in this project can be usefull when generating code any UML 2.5.1 model.

For a tutorial on how to get started with code generation, please read more here

The project contains Generators, Templates and a ModelTransformer.

Generators

The generators are classes used to generate code. In the case of uml4net the following kinds of code are generated:

  • POCO: C# classes of each concrete Class in the UML2.5.1 model.
  • Interfaces: C# interfaces of all Classes in the UML2.5.1 model.
  • Enumerations: C# enum of each Enumeration in the UML2.5.1 model.
  • XmiElementReader: An XmiElementReader{T} for each concrete Class in the UML2.5.1 model.
  • XmiElementReaderFacade: A Facade/Factory class that returns a an instance XmiElementReader{T} based on the name of the class that is to be parsed, i.e. uml:Class -> ClassReader

A specific generator, for example the XmiReaderGenerator, registers the required Handlebars helpers, the required templates, and implements the GenerateAsync method.

Base classes

Each generator derives from the HandleBarsGenerator which takes care of the registration of the handlebars templates and HandleBars helpers.

The HandleBarsGenerator class in turn derives from the Generator class. The Generator class is responsible for cleaning up C# code and writing the resulting files to disk. Code cleanup uses the Microsoft.CodeAnalysis to format the whitespace of a syntax tree.

Currently only a Handlebars.Net based generator is used, other technologies such as T4 or DotLiquid could be used as. These would then have their own generic base class.

Templates

A handlebars template is used for dynamic content generation. The templates are simple, almost logic-less templates that work by replacing placeholders with data. Templates are written in plain text and are parsed by the library at runtime and with objects or dictionaries for data binding. The Placeholders enclosed in double curly braces {{ }}. Full documentation can be found here.

A partial example of a Handlebars template is provided below. The snippet demonstrates how the constructor of the XmiElementReaderFacade is generated where the readerCache is set initialized with a new Dictionary. The contents of the dictionary is generated on the basis of all the concrete classes in the model. The object that is passed to the template is an List<IClass> which is the context of the Template and can be accessed with the this variable in the template. With the {{ #each this as | class | }} ... {{/each}} block, a key-value paris is added to the dictionary.

public XmiElementReaderFacade()
{
    readerCache = new Dictionary<string, Func<IXmiElementCache, ILoggerFactory, XmlReader, IXmiElement>>
    {
        {{ #each this as | class | }}
        ["uml:{{ class.Name }}"] = (cache, loggerFactory, xmlReader) =>
        {
            using var subXmlReader = xmlReader.ReadSubtree();
            var {{ String.LowerCaseFirstLetter class.Name }}Reader = new {{ class.Name }}Reader(cache, this, loggerFactory);
            return {{ String.LowerCaseFirstLetter class.Name }}Reader.Read(subXmlReader);
        },
        {{/each}}
    };
}

Transformers

In some cases it may be necessary to transform a UML model to make it fit for purpose in C#. The following transformation rule is applied using the ModelTransformer'.

  • The UML 2.5.1 model contains a Class that contains a property that has the same name as the owning Class. This is not allowed in C#. In order to overcome this, an s is appended to the property name. The result is that valid C# code can be generated.

This transformer is very specific to this model and may not be required in other UML models.