Skip to main content

JinShil.MixinSourceGenerator by Jin Shil

NuGet / site data

Nuget GitHub last commit GitHub Repo stars

Details

Info

info

Name: JinShil.MixinSourceGenerator

A C# source generator for composing classes or structs from other classes or structs using mixins.

Author: Jin Shil

NuGet: https://www.nuget.org/packages/JinShil.MixinSourceGenerator/

You can find more details at https://github.com/JinShil/JinShil.MixinSourceGenerator

Source: https://github.com/JinShil/JinShil.MixinSourceGenerator

Author

note

Jin Shil Alt text

Original Readme

note

JinShil.MixinSourceGenerator

NuGet Version

This is a very simple, but powerful C# source generator that simplifies class and struct composition through the use of mixins.

It dramatically increases code reuse by copying members, including attributes and XML comments, verbatim from one or more implementation types to another type. The resulting type becomes a composition of the implementation types without employing inheritance, extensions, default interface methods, or any other specialized language feature.

It simply copies and pastes members from one or more types into another.

Example

The following example demonstrates how to use this source generator to compose a class from two implementation classes.

  1. Apply one or more [Mixin(typeof(TypeToMixIn))] attributes to a partial class or struct, specifying the types to mix in.
  2. The source generator scans for the specified types and copies their members, including attributes and XML comments, verbatim into the attributed type.

Source Code

internal class Implementation1
{
/// <summary>
/// Summary for Property1
/// </summary>
[SomeAttribute]
public int Property1 \{ get; }

/// <summary>
/// Summary for Method1
/// </summary>
[SomeAttribute]
public void Method1()
{
Console.WriteLine("Running Method 1");
}
}
internal class Implementation2
{
/// <summary>
/// Summary for Property2
/// </summary>
[SomeAttribute]
public int Property2 \{ get; }

/// <summary>
/// Summary for Method2
/// </summary>
[SomeAttribute]
public void Method2()
{
Console.WriteLine("Running Method 2");
}
}
[Mixin(typeof(Implementation1))]
[Mixin(typeof(Implementation2))]
public partial class Composition : SomeBaseClass, ISomeInterface
{
}

Generated Code

The above code will result in the following generated code, a composition of Implementation1 and Implementation2.

[Mixin(typeof(Implementation1))]
[Mixin(typeof(Implementation2))]
public partial class Composition : SomeBaseClass, ISomeInterface
{
/// <summary>
/// Summary for Property1
/// </summary>
[SomeAttribute]
public int Property1 \{ get; }

/// <summary>
/// Summary for Method1
/// </summary>
[SomeAttribute]
public void Method1()
{
Console.WriteLine("Running Method 1");
}

/// <summary>
/// Summary for Property2
/// </summary>
[SomeAttribute]
public int Property2 \{ get; }

/// <summary>
/// Summary for Method2
/// </summary>
[SomeAttribute]
public void Method2()
{
Console.WriteLine("Running Method 2");
}
}

The [MixinIgnore] Attribute

The [MixinIgnore] attribute can be added to implementation type members, allowing the implementation type to compile, but deferring the member's implementation to the composed type.

Source Code

internal class Implementation
{
// The source generator will not copy this method into any composition type.
// This member is effectively just a stub, so that this implementation class will compile.
[MixinIgnore]
void Method1()
\{ }

/// <summary>
/// Summary of Method2
/// </summary>
public void Method2()
{
Method1();
}
}
[Mixin(typeof(Implementation))]
public partial class Composition
{
/// <summary>
/// Summary of Method1
/// </summary>
public void Method1()
{
Console.WriteLine("Running Method1");
}
}

Generated Code

The above code will result in the following generated code. Implementation.Method2() will call Composition.Method1(), not Implementation.Method1().

public partial class Composition
{
/// <summary>
/// Summary of Method1
/// </summary>
public void Method1()
{
Console.WriteLine("Running Method1");
}

/// <summary>
/// Summary of Method2
/// </summary>
public void Method2()
{
Method1();
}
}

License

This repository is licensed under the GNU General Public License (GPL). The GPL applies only to the source code in this repository. Code generated by the source generator is not subject to this license and can be used according to your own project's licensing terms.

About

note

Generate mixins of classes

How to use

Example (source csproj, source files)

This is the CSharp Project that references JinShil.MixinSourceGenerator

<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="JinShil.MixinSourceGenerator" Version="1.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>

Generated Files

Those are taken from $(BaseIntermediateOutputPath)\GX


namespace JinShil.MixinSourceGenerator
{
/// <summary>
/// Specifies the type whose members are to be mixed in to a partial class or struct.
/// </summary>
[System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Struct, AllowMultiple = true)]
public class MixinAttribute : System.Attribute
{
public System.Type Type \{ get; }
public MixinAttribute(System.Type type)
{
Type = type;
}
}
}

Useful

Download Example (.NET C#)

Share JinShil.MixinSourceGenerator

https://ignatandrei.github.io/RSCG_Examples/v2/docs/JinShil.MixinSourceGenerator

Category "Mixin" has the following generators:

1 JinShil.MixinSourceGenerator

2 Minerals.AutoMixins

3 MorrisMoxy

See category

Mixin