Mixins in .NET


Posted on December 14th, by Arnon Rotem-Gal-Oz in Blog. 4 comments

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 which requires you implement a <=> method telling it what to compare, and you get all the comparing operators (<,<=,==..)

1
2
3
4
5
6
class Car
  include Comparable
  def <=>(other)
    self.year <=> other.year
  end
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
2
3
4
5
6
7
8
9
10
11
12
13
14
private class sortYearAscendingHelper : IComparer
{
    int IComparer.Compare(object a, object b)
        {
           car c1=(car)a;
           car c2=(car)b;
           if (c1.year > c2.year)
                 return 1;
           if (c1.year < c2.year)
                return -1;
            else
                return 0;
       }
}

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

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
2
3
4
5
6
7
internal class SomeHandler : IHandle<ISignalEndOfRun>
{
      public void Handle(ISignalEndOfRun evt)
      {
          //Do something
      }
}

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

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. Not a perfect solution but useful non-the-less


Illustration by

Tweet about this on Twitter5Share on LinkedIn0Share on Facebook0Share on Google+1Buffer this pageShare on Reddit0Share on StumbleUpon0Email this to someone




  • http://kenegozi.com/blog Ken Egozi

    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)

  • Pingback: Tweets that mention Mixins in C# .NET | Cirrus Minor -- Topsy.com

  • http://arnon.me Arnon Rotem-Gal-Oz

    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  :)
  • Pingback: Mixins in .NET