Skip to content

Mixins in .NET

Mixins are a good way to weave functionality into a class. Wikipedia defines Mixin as follows.

“In object-oriented programming languages, a mixin is a class that provides a certain functionality to be inherited by a subclass, while not meant for instantiation (the generation of objects of that class). Inheriting from a mixin is not a form of specialization but is rather a means of collecting functionality. A class may inherit most or all of its functionality from one or more mixins through multiple inheritance.”

Nice languages have mixins as part of the language spec. Ruby, for example, supports mixins through the notion of Modules, a way to group in related methods (and classes and constants), which is not a class in itself. You can program a bit of logic that interacts with the class it is hosted in, effectively letting you get multiple inheritance in a decent manner. For example, Ruby has a Comparable mixin that requires you to implement a <=> method telling it what to compare, and you get all the comparing operators (<,<=,==..)

  1. class Car
  2.   include Comparable
  3.   def <=>(other)
  4.     self.year <=> other.year
  5.   end
  6. end

Compare that (sorry for the pun) to C# where you need to inherit an interface and implement all the code yourself. If we had a similar Car class in C# and we’d want to sort it by year we’d have to implement IComparer.Compare() method (per the example from KB320277 “How to use the IComparable and IComparer interfaces in Visual C#.”

  1. private class sortYearAscendingHelper : IComparer
  2. {
  3.     int IComparer.Compare(object a, object b)
  4.         {
  5.            car c1=(car)a;
  6.            car c2=(car)b;
  7.            if (c1.year > c2.year)
  8.                  return 1;
  9.            if (c1.year < c2.year)
  10.                 return -1;
  11.             else
  12.                 return 0;
  13.        }
  14. }

Actually, C# has a weak notion of Modules which is called Static Classes and Extension method. It is weak since the the extension methods (and other methods in the static classes) need to be static, which is limiting. In many cases, though, combining interfaces with extension methods gets you a reasonable mixin effect.

For example, in my current project, we have profiling events that bubble up e.g. the profiling run completed – that would mean the class would implement the ISignalEndOfRun interface, which inherits the ImProfilingEvent interface.

Then I have some code that holds handlers (implementing an ImHandler interface) and passes the events to the handlers

  1. private List<ImHandler> handlers = new List<ImHandler>();
  2. public void HandleEvnet(ImProfilingEvent profilingEvent)
  3. {
  4.      foreach (var handler in handlers)
  5.      {
  6.          handler.Handle(profilingEvent);
  7.      }
  8. }

And  I want only the handlers that actually handle the specific event to do so. I also want to keep the handlers clean so a handler would look something like:

  1. internal class SomeHandler : IHandle<ISignalEndOfRun>
  2. {
  3.       public void Handle(ISignalEndOfRun evt)
  4.       {
  5.           //Do something
  6.       }
  7. }

And I can do that and have everything wired and working correctly if I make the  IHandle interface a mixin. Here’s what it looks like:

  1. public interface ImHandler
  2. {
  3.          IEnumerable<Result> GetResults();
  4. }
  5. public interface IHandle<in TProfilingEvent> : ImHandler where TProfilingEvent:ImProfilingEvent
  6. {
  7.          void Handle(TProfilingEvent evt);
  8. }
  9. internal static class HandlerExtensions
  10. {
  11.         public static void Handle(this ImHandler handler, ImProfilingEvent profilingEvent)
  12.         {
  13.                var handlerInterfaces = /* Find the generic IHandle<> interfaces of the handler  */
  14.                handler.GetType().GetInterfaces().Where(
  15.                           i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IHandle<>));
  16.                if (handlerInterfaces.Count() == 0) return;
  17.  
  18.                var profilerEventInterfaces = FindProfileEventinterface(profilingEvent, handlerInterfaces);
  19.                foreach (var handlerInterface in handlerInterfaces)
  20.                {
  21.                       if (handlerInterface.GetGenericArguments().First() == profilerEventInterfaces)
  22.                       {
  23.                             var method = handlerInterface.GetMethod("Handle");
  24.                             var param = new object[] { profilingEvent };
  25.                             method.Invoke(handler, param); // .NET is nice enough to upcast  ImProfilinfEvent coming back from object
  26.                       }
  27.                }
  28.         }
  29.         private static Type FindProfileEventinterface(ImProfilingEvent profilingEvent, IEnumerable<Type> handlerInterfaces)
  30.         {
  31.                var profilerEventInterfaces = /* find the profiling event*/
  32.                profilingEvent.GetType().GetInterfaces().Where(
  33.                     i => i != typeof(ImProfilingEvent) && handlerInterfaces.Any(h => h.GetGenericArguments().First() == i));
  34.  
  35.               if (profilerEventInterfaces.Count() > 1) throw new ArgumentException("Multi-events not supported");
  36.               if (profilerEventInterfaces.Count() == 0) throw new ArgumentException("invalid profilerEvent");
  37.               return profilerEventInterfaces.First();
  38.         }
  39. }

While this particular example uses some funky reflection to do auto-wiring (I know there are other ways to do that, but that’s how I am :) ), you can write simpler mixins that define some stuff in the interface and then go about using that, and building some logic on it in the extension methods you provide with it. It is not a perfect solution but it is useful non-the-less


Illustration by

Published inBlog

4 Comments

  1. your c#<->ruby comparison is unfair.The Ruby version uses the internal default comparer for integer values when comparing Year, that why it looks short and neat, while your c# version go about re-implementing that.Instead, you could’ve used   Comparer<int>.Default.Compare(a.Year, b.Year)Ruby is a nice language in terms of syntactic sugar. It also is quite a mess (see the syntax changes from 1.8.x to 1.9 and the adoption pain of those. Ruby 2 will probably piss a lot of people)

  2. Hi Ken, 

    You may be right – but the point of this post is not how great ruby is vs. C# but rather how great mixins are  and  how to do them in C#  so I don’t see this as much of a problem  :)
  3. […] a class that provides a certain functionality to be inherited by a subclass, while not meant for… [full post] Arnon Rotem-Gal-Oz Cirrus Minor blog.netc#cloudoscope 0 0 0 […]

Comments are closed.