Friday, August 17, 2012

How do mixins work in C#?

Extension methods which target a common marker interface can be viewed as partial implementations of that interface.

If you place such extension methods in different namespaces then it is possible to utilize a technique of "Mixing In" the implementations used by a class.

This is demonstrated in code below.  The one part of this that I took a minute to get my head around was that ILogger loses the semantics of an interface.  The methods available to it are those extension methods which are visible to the compiler as dictated by the using statements.

Some links I learned from before writing this:
namespace MixinDemo
{
public interface ILogger
{
}
}
view raw ILogger.cs hosted with ❤ by GitHub
using System;
namespace MixinDemo.Logger1.Log
{
public static class Mixin
{
public static void Log(this ILogger logger, string message)
{
Console.WriteLine("Logger1 Log: " + message);
}
}
}
view raw Log.cs hosted with ❤ by GitHub
using System;
namespace MixinDemo.Logger2.LogError
{
public static class Mixin
{
public static void LogError(this ILogger logger, string message)
{
Console.WriteLine("Logger2 LogError: " + message);
}
}
}
view raw LogError.cs hosted with ❤ by GitHub
using System;
namespace MixinDemo
{
// Mix in the ILogger functionality required by the implementation of the Program class
using Logger1.Log;
using Logger2.LogError;
class Program
{
ILogger logger = null; // OK to leave uninitialized since only extension methods will be called
static void Main(string[] args)
{
new Program().Execute();
}
private void Execute()
{
try
{
logger.Log("Hello World");
(null as object).GetType(); // error
}
catch (Exception ex)
{
logger.LogError(ex.Message);
}
}
}
}
view raw Program.cs hosted with ❤ by GitHub

No comments:

Post a Comment