Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Mixins in .NET

DZone's Guide to

Mixins in .NET

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

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#”

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

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:

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:

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

Topics:

Published at DZone with permission of Arnon Rotem-gal-oz, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}