Tuesday, 8 April 2014

C# Property by reference

I wanted to write a generic function to test a validation method of my object, but I wanted the function to be able to manipulate specific properties, like turning boolean values on or off.

Now one possibility is to pass the value by reference which is often something I don't like very much, but won't get into that too much right now, but since we are dealing with properties here the usual more elegant way is to create a wrapper or lambda function of some kind.

Now natrually before coding anything a quick google/SO search reveals some basic solutions and as one might expect involves some reflection as one CodeProject article here.

However I usually use dynamic reflection as a last resort as there is too much room for error here and referring to fields as strings just doesn't seem like the cleanest way. Also a super simple solution is by an SO post made here  (scroll down a bit) which simply just uses a small wrapper class you specifiy the getter and setter using 2 lambda expressions. This is certainly clean and simple, which I like, however I tried to create a function even simpler and more concise which also uses the compiler to ensure correctness, so I came up with this.

So much like the first version to use some reflection except no strings but using expressions. First extracting the property info from the expression, a nice clean wrapper object to help with this from this SO post:

public static class PropertyHelper<T>
 public static PropertyInfo GetProperty<TValue>(
  Expression<Func<T, TValue>> selector)
  {
  Expression body = selector;
  if (body is LambdaExpression)
  {
   body = ((LambdaExpression)body).Body;
  }
  
  switch (body.NodeType)
  {
   case ExpressionType.MemberAccess:
    return (PropertyInfo)((MemberExpression)body).Member;
    break;
   default:
    throw new InvalidOperationException();
  }
  }
}

So taking that a little further, creating a helper class to generate a lambda getter and setter

public static class PropertyHelper
{
 public static Func<TValue> GetPropertyGetter<T, TValue>(T value, Expression<Func<T, TValue>> selector)
 {
  var propInfo = (PropertyInfo)((MemberExpression)(selector).Body).Member;
  return () => (TValue)propInfo.GetValue(value, null);
 }

 public static Action<TValue> GetPropertySetter<T, TValue>(T value, Expression<Func<T, TValue>> selector)
 {
  var propInfo = (PropertyInfo)((MemberExpression)(selector).Body).Member;
  return v => propInfo.SetValue(value, v, null);
 }
}

Small note: This requires you to use a lambda expression for the property any other expression will break it, I didn't add all the checks to make it more terse. So Then the usage would simply be:
var getter = PropertyHelper.GetPropertyGetter(world, w => w.Hello);
var setter = PropertyHelper.GetPropertySetter(world, w => w.Hello);

And then you can get the property by calling:

getter();
setter("Hello");

Extending that a little further by adding a nice wrapper class:

public class PropertyWrapper<TValue> : IPropertyWrapper<TValue>
{
 protected PropertyInfo _propInfo;
 protected object _instance;

 public PropertyWrapper(PropertyInfo propinfo, object instance)
 {
  _instance = instance;
  _propInfo = propinfo;
 }

 public object Instance
 {
  get { return _instance; }
 }

 public TValue Value
 {
  get { return (TValue)_propInfo.GetValue(_instance, null); }

  set
  {
   _propInfo.SetValue(_instance, value, null);
  }
 }
}

Then you can pass around the wrappers:
var wrapper = PropertyHelper.GetPropertyWrapper(world, w => w.Hello)
Now you can easily use this in your generic method and manipulate any property:
  
private static void TestCondition(IPropertyWrapper condition)
{
 condition.Value = false;
 Console.WriteLine(condition.Instance.Validate());
 condition.Value = true;
 Console.WriteLine(condition.Instance.Validate());
}
Dynamic objects are of course another way to do this however you then still are missing out on the compile time checking, so I haven't coded out this solution, but I think I'd still rather use this approach then reflection by string name method. So there you have it, this seems like a nice clean way to create property references, you can take it one more step further by creating an object extension method for this, but I usually try to avoid this as it can clutter up the code completion just a little bit too much. But if you can think of an even better cleaner way in C#

Monday, 4 November 2013

Abstractions

After reading this interesting article: Abstracting away and Abstracting into it made me think of an argument discussion with a friend regarding this very topic. I was under the belief that when I was implementing logging for my application I would be best off to create my own ILog interface. And then creating wrappers that would encapsulate either Log4Net or NLog. My motivation was that Log4Net for example provides 50+ methods that I didn't need and that I wanted something for my application with just 3 methods:
LogMessage, LogWarning, LogError
I also wanted something easy to mock and unit test. The fact that this is logging is interesting because it is so ubiquitous, meaning whichever way I go could by coupled to nearly every single class.

One way we can address the problem by merely keeping the usage on the outskirts of the application. A good example of this are IOC containers. It doesn't really matter which library we use as the client code will not use it directly. This might seem impossible with the logging example but there are techniques such as creating logging aspects (AOP) but we won't go into that here.

In hindsight I feel that I was wrong about some things but right about some other. I didn't need to abstract Log4Net due to testing needs. Log4Net does already have an ILog interface and this does make it mockable and testable. And even though it has 50+ methods to mock do you even need to bother? In a unit testing scenario your config is set up to just print to the console, no mocking needed. However addressing the 2nd problem of swapping our libraries, do you even need to? Even if you have a project that you plan will live for 5-10+ years Log4Net will probably out live it. Also this particular example the library is proven and well established.

Also by creating my own interface I really thought that this is all I would need now, but in future I end up needing more, and in time I will just duplicate the effort of the library I am abstracting. This will unfortunately create the same inevitability which is the more abstractions I leak the more I am implicitly tying myself to that library anyway and ultimately I will introduce a piece of functionality that only the one library will support and switching will be impossible.

Of course I have seen many times where companies and projects have heavily embraced and invested in library X and then due to fading support or features were forced to move to Y and requiring large portions of the code base to be re written. In the cases I mention even if we created an abstraction to either X or Y there were such fundamental differences between what these graphics libraries supported from each other that a common abstraction wasn't possible and would more than likely just water down our interfaces leaving very little point of using either of them.

In this case though it is important that we use certain patterns for development for instance if we were using a graphics library and using the MVC or MVP pattern, in this unlikelihood we certainly could just replace our views and keep all business logic in tact. Also patterns like AOP mentioned above.

So as long as the library provides ways to mock and unit test and unless you are using a new very experimental library you are probably better to abstract into.

This is my honest advice for best business value, of course if I was writing something for myself I would certainly add layers and abstractions, because its more fun, but that's another story...