Skip to content
This repository has been archived by the owner on May 19, 2023. It is now read-only.

Experimental Roslyn Source Generator for Kentico Kontent

Notifications You must be signed in to change notification settings

petrsvihlik/kontent-source-generator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Experimental Roslyn Source Generator for Kentico Kontent

This project tries to demonstrate the power of Roslyn's C# Source Generators for generating POCO models for Kentico Kontent apps writtein in C#. It's based on an implementation of the Microsoft.CodeAnalysis.ISourceGenerator interface decorated by the Microsoft.CodeAnalysis.GeneratorAttribute.

Motivation

The main advantage of this approach is that one doesn't have to run any external app to keep their models in sync with Kentico Kontent's content model. The models are added dynamically to the Compilation object without the user even noticing. One can start using the models as soon as the [assembly: GenerateKontentModelsFor(ProjectId)] attribute is added to the project and the models will always be up to date.

Read more here: kontent-ai/model-generator-net#103

Prerequisites

Usage

  • Reference the Kentico.Kontent.SourceGenerator project <ProjectReference Include="..\Kentico.Kontent.SourceGenerator\Kentico.Kontent.SourceGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
  • Add an assembly-level attribute [assembly: GenerateKontentModelsFor("<your-project-id>")]
  • You can start using your models (e.g. await client.GetItemsAsync<Article>())

Complete example

Solution

As you can see, there are no additional files in the project. All models are being added dynamically during the compile time.

Program.cs

using System;
using System.Threading.Tasks;
using Kentico.Kontent.Delivery.Abstractions;
using Kentico.Kontent.Delivery.Builders.DeliveryClient;
using KenticoKontentModels;
using static Kentico.Kontent.SourceGenerator.Demo.Program;

[assembly: GenerateKontentModelsFor(ProjectId)]

namespace Kentico.Kontent.SourceGenerator.Demo
{
    class Program
    {
        public const string ProjectId = "975bf280-fd91-488c-994c-2f04416e5ee3";

        public static async Task Main(string[] args)
        {
            IDeliveryClient client = DeliveryClientBuilder.WithProjectId(ProjectId).WithTypeProvider(new CustomTypeProvider()).Build();
            var articles = await client.GetItemsAsync<Article>();
            foreach (var article in articles.Items)
            {
                Console.WriteLine($"The article '{article.Title}' was posted on {article.PostDate.Value.ToShortDateString()}.");
            }
            Console.ReadLine();
        }
    }
}

Output: Console App

Known Issues

  • Publishing / referencing Kentico.Kontent.SourceGenerator as a NuGet package doesn't work ATM
  • Tests don't work
  • [[Roslyn Blocker]] Currently, it's not possible to add transitive NuGet references and adding 1st-level references is unhandy. This is worked around by the combination of <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> and a lightweight implementation of IDeliveryClient to avoid referencing Kentico.Kontent.Delivery with conflicting references