Thursday, 20 October 2011

C# Enum Visitor Pattern

I have not written for a while and in fact it is too long and shameful.

I was working on a bunch of ideas but haven’t been able to get it finished, but i want to start now and focus on some patterns for a while and starting with this:

Suppose we have an enum like this:

public enum LifeCycle
{
    Transient,
    ThreadLocal,
    Singleton
}

Now lets just pretend that we want to make various decisions and perform operations or tasks based on which enum has been selected.
In this particular case i want to construct an object that represents the enum. 
 
You may think this is a factory pattern or strategy/factory map so therefore I can construct a strategy and make it visitible by adding an Accept method.
 
The problem with this as i mentioned is that the operation could really be anything and I want something generic that could be used for any enum.
 

I wanted to see the validity of this approach and what others may think so I wanted feedback from the community, so see my question on stackoverflow.

And also I didn’t want the user of this code to go and create a strategy class for each type.

Now lets say I define a set of values (in this case classes)

public class LifeCycleBase { }
public class SingletonLifeCycle : LifeCycleBase { }
public class ThreadLocalLifeCycle : LifeCycleBase { }
public class TransientLifeCycle : LifeCycleBase { }

I want these returned for each condition would normally result in code like this:

switch (lifeCycle)
{
case LifeCycle.Singleton:
return new SingletonLifeCycle();
case LifeCycle.ThreadLocal:
return new ThreadLocalLifeCycle();
case LifeCycle.Transient:
return new TransientLifeCycle();
default:
throw new Exception("Unsupported LifeCycle: " + lifeCycle.ToString());
}

So we might in one case have an operation that returns a class like a strategy per enum, in another case we might want to just return a string representing the type or any other arbitrary operation.

In creating a more OO solution you could use a strategy class as mentioned, but this would result in a consumer creating a class for each enumeration and then for each different strategy based on the enumeration.

The second solution is to use a visitor pattern. This is more appropriate than the strategies as one class groups together a collection of operators using double dispatch.

In either case this results in quite a bit of plumbing.

So what I want is:

      1. A solution that is VERY easy to implement
      2. Requires minimal plumbing
      3. Is very generic and reusable
      4. Performs well
      5. Is type safe

I thought I would like to be using something like this:

EnumVisitorHelper.Accept<LifeCycleBase>(lifeCycle, new MyLifeCycleEnumVisitor());

And that THIS, would be very easy to use and much better from an OO perspective.

The visitor loos like this:

public class MyLifeCycleEnumVisitor
{
public override LifeCycleBase VisitTransientLifeCycle()
{
return new TransientLifeCycle();
}

public override LifeCycleBase VisitSingletonLifeCycle()
{
return new SingletonLifeCycle();
}

public override LifeCycleBase VisitThreadLocalLifeCycle()
{
return new ThreadLocalLifeCycle();
}
}

This is the helper:

public class EnumVisitorHelper
{
public static T Accept<T>(System.Enum theEnum, object visitor)
{
var methodName = string.Format("Visit{0}{1}", theEnum.ToString(), theEnum.GetType().Name);
foreach (var method in visitor.GetType().GetMethods())
{
bool acceptable = method.Name == methodName;

if (acceptable) acceptable = typeof(T).IsAssignableFrom(method.ReturnType);
if (acceptable)
{
return (T)method.Invoke(visitor, new object[] { });
}
}
throw new Exception("Method not found");
}
}

It will use reflection to double-dispatch onto the visitor based on the name of the enumeration.

This is certainly

  1. Easy to use
  2. Minimal Plumbing
  3. Good OO
  4. Is Generic and Reusable

BUT ITS NOT:

The best performing

Not 100% type safe as an enumeration may change and could break some visitors.

You will also notice the lack of a Visitible, this is more of a double-dispatch pattern than visitor but if we wont get too technical it still works.

So I thought how to fix these problems and first i thought to create a Visitible interface:

public interface IVisitible
{
T Accept<T>(object visitor);
}

And then I wanted a factory to construct a Visitible:

public static class EnumVisitibleFactory
{
public static IVisitible Create(System.Enum enumeration)
{
return new EnumVisitible(enumeration);
}
}

But in order to double dispatch I can either automatically map back to the enum name, but this would not be type safe. So I thought of using attributes instead:

public class EnumVisitor : Attribute
{
public object Enumeration { get; set; }

public EnumVisitor(object enumeration)
{
this.Enumeration = enumeration;
}
}

Now my visitor can be decorated as follows:

public abstract class MyLifeCicleVisitorBase<T>
{
[EnumVisitor(LifeCycle.Transient)]
public abstract T VisitTransientLifeCycle();
[EnumVisitor(LifeCycle.Singleton)]
public abstract T VisitSingletonLifeCycle();
[EnumVisitor(LifeCycle.ThreadLocal)]
public abstract T VisitThreadLocalLifeCycle();
}

Now an attribute decides which is the visitor method also the method essentially can now be your name of choice. Lastly this gives you some type safety that you will get compiler help once there is a enum breaking change.

This is the concrete Visitible:

public class EnumVisitible : IVisitible
{
private object _enumeration;
public EnumVisitible(System.Enum enumeration)
{
this._enumeration = enumeration;
}

private static readonly Dictionary<Type, Dictionary<object, MethodWrapper>> _staticMap =
new Dictionary<Type, Dictionary<object, MethodWrapper>>();
private static readonly object _syncLock = new object();

MethodWrapper Map(object visitor)
{
foreach (var method in visitor.GetType().GetMethods())
{
var attributes = method.GetCustomAttributes(typeof(EnumVisitor), true);
if (attributes.Length > 0)
{
var attr = (EnumVisitor)attributes[0];
if (attr.Enumeration.Equals(this._enumeration))
{
return new MethodWrapper(method);
}
}
}
throw new Exception(string.Format("Enumeration: {0} not mapped", this._enumeration.ToString()));
}

MethodWrapper GetCachedMap(object visitor)
{
var type = visitor.GetType();
Dictionary<object, MethodWrapper> enumToMetodInfoMap = null;
MethodWrapper mi = null;

bool found = false;

lock (_syncLock)
{
found = _staticMap.TryGetValue(type, out enumToMetodInfoMap);
if (!found)
{
enumToMetodInfoMap = new Dictionary<object, MethodWrapper>();
_staticMap[type] = enumToMetodInfoMap;
}
}

lock (_syncLock)
{
found = enumToMetodInfoMap.TryGetValue(this._enumeration, out mi);
}
if (!found)
{
mi = Map(visitor);
lock (_syncLock)
{
enumToMetodInfoMap[this._enumeration] = mi;
}
}
return mi;

}

#region IVisitible Members

public T Accept<T>(object visitor)
{
var method = this.GetCachedMap(visitor);
var parameters = method.GetParameters();
var inParameters = new List<object>();
foreach (var parameter in parameters)
{
object inParam = null;
if (parameter.ParameterType.IsAssignableFrom(typeof(IVisitible)))
{
inParam = this;
}
inParameters.Add(inParam);
}
return (T)method.Invoke(visitor, inParameters.ToArray());
}

#endregion
}

public class MethodWrapper
{
private MethodInfo _methodInfo;
private IMethodInvoker _invoker;

public ParameterInfo[] GetParameters()
{
return this._methodInfo.GetParameters();
}

public MethodWrapper(MethodInfo methodInfo)
{
this._methodInfo = methodInfo;
this._invoker = new MethodInvoker(methodInfo);
}

internal object Invoke(object visitor, object[] p)
{
return this._invoker.Invoke(visitor, p);
}
}

Now I can use it like this:

EnumVisitibleFactory.Create(lifeCycle).Accept<LifeCycleBase>(new MyLifeCycleEnumVisitor())

EDIT: I can further improve things with an extension:

public static class EnumExtensions
{
public static IVisitible CreateVisitible(this Enum value)
{
return EnumVisitibleFactory.Create(value);
}

public static TResult Accept<TResult>(this Enum value, object visitor)
{
return EnumVisitibleFactory.Create(value).Accept<TResult>(visitor);
}
}

Then the usage becomes EVEN NICER:

LifeCycle.Singleton.Accept<LifeCycleBase>(new MyLifeCycleEnumVisitor());

This is now more OO, generic fast (as its using a static dictionary).

Wednesday, 17 August 2011

The Dynamic Landscape

 

The ‘dynamic’ keyword is new to C# 4.0.

 

The DLR is a major new feature of the language that changed the way we can do API’s and interface with dynamic languages forever.

 

In this article I will show you what is available and briefly touch on scenarios you may use it.

 

Any object may be declared as dynamic and will automatically become late-bound:

dynamic i = 1;
Console.WriteLine(i + 1);

image

Consider a method that takes in a dynamic variable:

image

Declaring the parameter as dynamic causes code completion to tell us that it will only be evaluated at run-time (late-bound).

Suppose our consumer method takes a dynamic object and tries to call the Hello method as follows:

void Consumer(dynamic worldObject)
{
    Console.WriteLine(worldObject.Hello());
}

We can pass in any object to this function and it will compile and run fine as long as by the time it is executed the worldObject has the method Hello().

We can declare any object and add this method:

class ConcreteObject
{
    public string Hello()
    {
       return "Hello";
    }
}
Consumer(new ConcreteObject());
image

ExpandoObject

With ExpandoObject we can create any object with any method or property we want at runtime:

dynamic dyn = new ExpandoObject();

We can add the method as follows:

Func<string> hello = () => "Hello";

dyn.Hello = hello;
Consumer(dyn);

Prints the same result:

image

DynamicObject

Is what we would use if we want even more control over a method or property as it is evaluated. It provides virtual methods that can be overwritten each time someone tries to call a method or read a member.

We can create a DynamicObject and create our own ExpandoObject:

class MyDynamicObject : DynamicObject
{
  Dictionary<string, dynamic> _members;
  public MyDynamicObject ()
  {
      _members = new Dictionary<string, dynamic>();
  }
  public void AddMember<T>(string name, T member)
  {
      _members[name] = member;
  }

  public override bool TryGetMember(GetMemberBinder binder, out object result)
  {
     result = _members[binder.Name];
     return true;
  }
  public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
  {
      var member = _members[binder.Name];
      Delegate del = (Delegate)member;
      result = del.DynamicInvoke(args);
      return true;
  }
}
We can then use it this way:
var myDynamicWrapper = new MyDynamicObject();
myDynamicWrapper.AddMember<Func<string>>("Hello", () => "Hello");
dynamic dyn = myDynamicWrapper;
Consumer(dyn);

And again we get this output:

image

Why

As the main point was not to try and tell you why you should care I think there are a few ideas to think about. The ‘dynamic’ wherever it comes up in conversation will certainly be a point of controversy, much more than when the ‘var’ keyword when it was introduced.

There are many articles where people debate this like this one.

"Static when possible; dynamic when necessary."

You may think you will never use this, and maybe all coding should be statically typed but if you are using Javascript you are writing dynamic code already!

Even though C# 4.0 introduced this feature for supporting dynamic languages doesn’t mean we can never use this.

Here are some scenarios you may want to consider using it (feel free to leave your comments if you can think of more)

Dynamic instead of reflection

Dynamic is far easier/cleaner and the compiler generates more efficient IL code than using reflection.

COM/APIs

Wherever you do not have concrete static interfaces and objects are only known at runtime this is the obvious choice.

HTML/XML

If you need to implement a DOM and had to look up nodes when you don’t have a statically generated schema.

Patterns

One pattern that comes to mind is the visitor. This is a hard pattern to implement in C# due to all the plumbing required and often the pattern itself is overly complicated for simple solutions. Creating a dynamic object and using the Expando for example we can create visitors and only implement the methods we are interested in.

Testing

Even though we can use dynamic proxies to easily test objects we could not easily, for instance testing private methods. I feel that this is not the real power. In dynamic programming every object can be replaced by another (a mock). This is not possible in a static language.

Final thoughts

There is a good chance you may not need to write dynamic code. Most people feel that static programming is more reliable because the compiler checks for errors.

I say the dynamic language’s biggest flaw can be its greatest strength if you consider from a testing perspective all dynamic code can be easily unit tested where static code can not always. Then I heard Scott Hanselman use the phrase: Some Duck Typing pragmatists say:

“The compiler is just another unit test”

So next time you write Javascript code spare a thought for the dynamic programming you are doing.