JinShil.MixinSourceGenerator
1.0.0
dotnet add package JinShil.MixinSourceGenerator --version 1.0.0
NuGet\Install-Package JinShil.MixinSourceGenerator -Version 1.0.0
<PackageReference Include="JinShil.MixinSourceGenerator" Version="1.0.0"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
<PackageVersion Include="JinShil.MixinSourceGenerator" Version="1.0.0" />
<PackageReference Include="JinShil.MixinSourceGenerator"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
paket add JinShil.MixinSourceGenerator --version 1.0.0
#r "nuget: JinShil.MixinSourceGenerator, 1.0.0"
#:package JinShil.MixinSourceGenerator@1.0.0
#addin nuget:?package=JinShil.MixinSourceGenerator&version=1.0.0
#tool nuget:?package=JinShil.MixinSourceGenerator&version=1.0.0
JinShil.MixinSourceGenerator
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.
- Apply one or more
[Mixin(typeof(TypeToMixIn))]
attributes to a partial class or struct, specifying the types to mix in. - 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]
attributed 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.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last Updated |
---|---|---|
1.0.0 | 126 | 7/17/2025 |
- Initial release.