KubeOps.Generator 13.0.0-prerelease.2

This is a prerelease version of KubeOps.Generator.
There is a newer version of this package available.
See the version list below for details.
dotnet add package KubeOps.Generator --version 13.0.0-prerelease.2
                    
NuGet\Install-Package KubeOps.Generator -Version 13.0.0-prerelease.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="KubeOps.Generator" Version="13.0.0-prerelease.2">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="KubeOps.Generator" Version="13.0.0-prerelease.2" />
                    
Directory.Packages.props
<PackageReference Include="KubeOps.Generator">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add KubeOps.Generator --version 13.0.0-prerelease.2
                    
#r "nuget: KubeOps.Generator, 13.0.0-prerelease.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package KubeOps.Generator@13.0.0-prerelease.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=KubeOps.Generator&version=13.0.0-prerelease.2&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=KubeOps.Generator&version=13.0.0-prerelease.2&prerelease
                    
Install as a Cake Tool

KubeOps Generator

NuGet NuGet Pre-Release

This is a C# source generator for KubeOps and operators. It is used to generate convenience functions to help register resources within an operator.

Motivation

The primary goal of this generator is to reduce boilerplate code required in your operator's Program.cs (or startup logic). Instead of manually calling builder.AddController<...>() and builder.AddFinalizer<...>() for every component, the generator scans your project and creates extension methods that register all discovered components with a single call.

Usage

The generator is automatically used when the KubeOps.Generator package is referenced.

dotnet add package KubeOps.Generator

which results in the following csproj reference:

<ItemGroup>
    <PackageReference Include="KubeOps.Generator" Version="...">
        <PrivateAssets>all</PrivateAssets>
        <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
    </PackageReference>
</ItemGroup>

Once referenced, you typically use the main generated extension method in your Program.cs:

using KubeOps.Operator;

var builder = WebApplication.CreateBuilder(args);

// Add KubeOps services and register all discovered components
builder.Services
    .AddKubernetesOperator()
    .RegisterComponents(); // <--- Generated extension method

// ... other service registrations

var app = builder.Build();
// ... configure middleware
app.RunOperatorAsync();

Generated Sources

The generator will automatically generate functions for the IOperatorBuilder.

By default, all shared classes (EntityDefinitions, EntityInitializer, ControllerRegistrations, FinalizerRegistrations, OperatorBuilderExtensions) are generated into the global namespace. Two general rules apply:

  • ControllerRegistrations / FinalizerRegistrations / EntityDefinitions / EntityInitializer are only generated when the compilation actually contains matching components.
  • OperatorBuilderExtensions (the RegisterComponents aggregate) and EntityInitializer are internal: they are only meaningful for the compilation they are generated into.

Configuring the Target Namespace

When multiple projects of one solution reference the generator (e.g. a class library with controllers and the operator itself), the generated class names must not conflict. Set the KubeOpsGeneratorNamespace MSBuild property in the participating projects to generate the shared classes into a distinct namespace instead of the global namespace:

<PropertyGroup>
    <KubeOpsGeneratorNamespace>$(RootNamespace)</KubeOpsGeneratorNamespace>
</PropertyGroup>

Any namespace works ($(RootNamespace), $(AssemblyName) or a literal); invalid characters are sanitized. Note that top-level Program.cs files then need a using directive for the configured namespace so that RegisterComponents() resolves.

Multi-Assembly Composition

Controllers and finalizers may live in referenced class libraries that also use the generator. Every assembly that contains such components is marked with an assembly-level KubeOps.Abstractions.Builder.KubeOpsGeneratedRegistrationsAttribute pointing to its (public) registration classes. These classes register only the components of their own assembly and never chain into further assemblies.

The generated RegisterComponents method of the consuming compilation discovers these markers on all transitively referenced assemblies and invokes every registration class exactly once via a fully qualified call:

using KubeOps.Abstractions.Builder;

[assembly: global::KubeOps.Abstractions.Builder.KubeOpsGeneratedRegistrations("MyOperator.ControllerRegistrations", "MyOperator.FinalizerRegistrations")]
namespace MyOperator;
internal static class OperatorBuilderExtensions
{
    public static IOperatorBuilder RegisterComponents(this IOperatorBuilder builder)
    {
        builder.RegisterControllers();
        builder.RegisterFinalizers();
        global::MyLibrary.ControllerRegistrations.RegisterControllers(builder);
        return builder;
    }
}

This flat, deduplicated composition guarantees that no component is registered twice, regardless of how the assemblies reference each other (e.g. app → LibA → LibB with components in all three).

If two assemblies in the chain generate registration classes with the same fully qualified name (e.g. both use the global namespace default), the generator reports the warning KOG002 and skips the conflicting registration instead of emitting ambiguous code. Set KubeOpsGeneratorNamespace in the conflicting projects to resolve it.

Entity Metadata / Entity Definitions

The generator creates a file named EntityDefinitions.g.cs (only when the compilation declares entities). This file contains all entities that are annotated with the KubernetesEntityAttribute and declared in the compilation itself - entities from referenced assemblies are listed by their declaring assembly. The static class contains the EntityMetadata for the entities.

Example
using KubeOps.Abstractions.Builder;
using KubeOps.Abstractions.Entities;

public static class EntityDefinitions
{
    public static readonly EntityMetadata V1TestEntity = new("TestEntity", "v1", "testing.dev", null);
    public static IOperatorBuilder RegisterEntities(this IOperatorBuilder builder)
    {
        builder.AddEntity<global::Operator.Entities.V1TestEntity>(V1TestEntity);
        return builder;
    }
}

Entity Initializer

All entities must have their Kind and ApiVersion fields set. To achieve this, the generator creates an initializer file for each entity that is annotated with the KubernetesEntityAttribute.

For each partial class that does not contain a default constructor, the generator will create a default constructor that sets the Kind and ApiVersion fields.

For each non-partial class, a method extension is created that sets the Kind and ApiVersion fields.

NOTE: Setting your class as partial is crucial for the generator to create the constructor. Also, if a default constructor is already present, the generator uses the method extension fallback.

Example
namespace Operator.Entities;

[KubernetesEntity(Group = "testing.dev", ApiVersion = "v1", Kind = "TestEntity")]
public partial class V1TestEntity : CustomKubernetesEntity
{
}

The partial defined entity above will generate the following V1TestEntity.init.g.cs file:

namespace Operator.Entities;
public partial class V1TestEntity
{
    public V1TestEntity()
    {
        ApiVersion = "testing.dev/v1";
        Kind = "TestEntity";
    }
}

The non-partial defined entity below:

namespace Operator.Entities;

[KubernetesEntity(Group = "testing.dev", ApiVersion = "v1", Kind = "TestEntity")]
public class V1TestEntity : CustomKubernetesEntity
{
}

will generate a static method extension in EntityInitializer.g.cs for the entity to initialize the fields:

public static class EntityInitializer
{
    public static global::Operator.Entities.V1ClusterTestEntity Initialize(this global::Operator.Entities.V1ClusterTestEntity entity)
    {
        entity.ApiVersion = "testing.dev/v1";
        entity.Kind = "ClusterTestEntity";
        return entity;
    }
}

Controller Registrations

The generator creates a file named ControllerRegistrations.g.cs (only when the compilation contains controllers). This file contains a function to register all found controllers (i.e., classes that implement the IResourceController<TEntity> interface).

Example
using KubeOps.Abstractions.Builder;

public static class ControllerRegistrations
{
    public static IOperatorBuilder RegisterControllers(this IOperatorBuilder builder)
    {
        builder.AddController<global::Operator.Controller.V1TestEntityController, global::Operator.Entities.V1TestEntity>();
        return builder;
    }
}

Finalizer Registrations

The generator creates a file named FinalizerRegistrations.g.cs (only when the compilation contains finalizers). This file contains all finalizers with generated finalizer identifiers. Further, a function to register all finalizers (i.e., classes that implement IResourceFinalizer<TEntity>) is generated.

Example
using KubeOps.Abstractions.Builder;

public static class FinalizerRegistrations
{
    public const string FinalizerOneIdentifier = "testing.dev/finalizeronefinalizer";
    public const string FinalizerTwoIdentifier = "testing.dev/finalizertwofinalizer";
    public static IOperatorBuilder RegisterFinalizers(this IOperatorBuilder builder)
    {
        builder.AddFinalizer<global::Operator.Finalizer.FinalizerOne, global::Operator.Entities.V1TestEntity>(FinalizerOneIdentifier);
        builder.AddFinalizer<global::Operator.Finalizer.FinalizerTwo, global::Operator.Entities.V1TestEntity>(FinalizerTwoIdentifier);
        return builder;
    }
}

General Operator Extensions

The generator creates a file named OperatorBuilder.g.cs. It contains the internal RegisterComponents convenience method that registers all generated sources: the components of the own compilation (only the parts that exist) and the components of all marked referenced assemblies (see Multi-Assembly Composition).

Example
using KubeOps.Abstractions.Builder;

[assembly: global::KubeOps.Abstractions.Builder.KubeOpsGeneratedRegistrations("ControllerRegistrations", "FinalizerRegistrations")]
internal static class OperatorBuilderExtensions
{
    public static IOperatorBuilder RegisterComponents(this IOperatorBuilder builder)
    {
        builder.RegisterControllers();
        builder.RegisterFinalizers();
        return builder;
    }
}

Troubleshooting

  • Generated files not visible? Source generators add files during the build process. They might not appear directly in your Visual Studio Solution Explorer unless you explicitly look in the obj/Debug/netX.Y/generated/KubeOps.Generator folder or use features like VS's "Show all files".
  • Changes not picked up? If you add a new controller/finalizer/webhook and it's not being registered, ensure your project compiles successfully and try rebuilding the solution.
  • Entity Initializer not working? Make sure your entity class is marked as partial and does not have an explicitly defined parameterless constructor if you want the generator to create one.
There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories (1)

Showing the top 1 popular GitHub repositories that depend on KubeOps.Generator:

Repository Stars
josephnhtam/live-streaming-server-net
A .NET implementation of RTMP live streaming server, supporting HTTP-FLV, WebSocket-FLV, HLS, Kubernetes, cloud storage services integration and more.
Version Downloads Last Updated
13.0.0 0 7/14/2026
13.0.0-prerelease.6 0 7/14/2026
13.0.0-prerelease.5 43 7/12/2026
13.0.0-prerelease.4 42 7/11/2026
13.0.0-prerelease.3 41 7/11/2026
13.0.0-prerelease.2 40 7/11/2026
13.0.0-prerelease.1 48 7/11/2026
12.1.0-prerelease.1 45 7/10/2026
12.0.1-prerelease.2 53 7/9/2026
12.0.1-prerelease.1 44 7/8/2026
12.0.0 255 7/7/2026
11.6.0-prerelease.1 61 7/3/2026
11.5.1-prerelease.2 59 7/2/2026
11.5.1-prerelease.1 56 7/2/2026
11.5.0 925 6/30/2026
11.5.0-prerelease.6 62 6/28/2026
11.5.0-prerelease.5 58 6/28/2026
11.5.0-prerelease.4 69 6/27/2026
11.5.0-prerelease.3 74 6/25/2026
11.5.0-prerelease.2 89 6/24/2026
Loading failed

'## [13.0.0-prerelease.2](https://github.com/dotnet/dotnet-operator-sdk/compare/v13.0.0-prerelease.1...v13.0.0-prerelease.2) (2026-07-11)

### ⚠ BREAKING CHANGES

* **generator:** support multi-assembly component composition (#1188)

### Features

* **generator:** support multi-assembly component composition ([#1188](https://github.com/dotnet/dotnet-operator-sdk/issues/1188)) ([443ed18](https://github.com/dotnet/dotnet-operator-sdk/commit/443ed18625e34c62f68d4d4e88be762ee534975c))
'