Skip to content

JinShil/JinShil.MixinSourceGenerator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

26 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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

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

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages