Skip to content

LokiMidgard/PartialMixins

Repository files navigation

NuGet Build status GitHub license

PartialMixins

Extends C# with Mixins. The Mixins are simulated using partial classes, instead of ilweaving like other librarys. The MixinAttribute copys all members of the targeted Mixin to a partial class implementation of the anotated type. This give you intellisense support on your classes. It uses the roslyn code generation framework.

Usage

First add the NuGet package to your Project.

To create a Mixin just declare a class.

    class IdMixin
    {
        public Guid Id { get; set; } = Guid.NewGuid();
    }

To apply the mixin you need to declare the MixinAttribute on the class that should implement the desired mixin. This class must also have the partial modifyer. Pass the Type of the Mixin in the attribute constructor. After the next time you build your source the mixin is implemented by your class.

    [Mixin(typeof(IdMixin))]
    partial class BusinessObject
    {
        public string Name { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var b1 = new BusinessObject() { Name = "Paul" };
            Console.WriteLine($"{b1.Id}:{b1.Name}");
        }

    }

Your mixins can also implement interfaces.

    interface Id : IEquatable<Id>
    {
        Guid Id { get; }
    }

    class IdMixin : Id
    {
        public Guid Id { get; set; } = Guid.NewGuid();

        public bool Equals(Id other) => Id.Equals(other.Id);

    }

If you use the Mixin Type itself, it will be substitueded with the consuming type.

    abstract class AddMixin
    {
        public abstract AddMixin Add(AddMixin other);
        public static AddMixin operator +(AddMixin a1, AddMixin a2)
        {
            return a1.Add(a2);
        }
    }

A Type that uses this Mixin may look like this:

namespace Sample
{
    [Mixin(typeof(AddMixin))]
    public partial struct MyNumber
    {
        public int Value { get; }
        public MyNumber(int value) => this.Value = value;
        public partial MyNumber Add(MyNumber other) => new MyNumber(this.Value + other.Value);
    }
}

// Generated Code...

namespace Sample
{
    public partial struct MyNumber
    {
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Mixin Task", "1.0.51.0")]
        public partial Sample.MyNumber Add(Sample.MyNumber other);
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Mixin Task", "1.0.51.0")]
        public static Sample.MyNumber operator +(Sample.MyNumber a1, Sample.MyNumber a2)
        {
            return a1.Add(a2);
        }
    }
}

As you can see absract methods are implemented as partial Methods. That way you can reqirer the consumer of your Mixin to provide specific functionallity.

Restrictions

  • The classes that implement the mixins must be partial.
  • Mixins may not have constructors.
  • Mixins may not have methods with the same method signiture then any other mixin that is implemented by the same class, or any method of the implementing class itself. (unless explicitly implemented methods of interfaces)
  • Mixins should not inhire from anything other than Object

Roadmap

  • Better compiletime error reporting
  • Generated source file shuold automaticly added to the Project
  • Automated NuGet build (ci)
  • Allow mixins of mixins. (As long it is no circal dependency)
  • Support for Generic Mixins
  • Better using conflict resolve strategy
  • Add GenerteadCodeAttribute to Methods and Propertys

Legal

This Software is licensed under MIT.

Used Assets

Icon Combine created by Paul Philippe Berthelon Bravo published under Public Domain.

About

Extends C# with Mixins.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages