Avoiding magic strings in LightSwitch (part 1)

Introduction

The weakly-typed Api in LightSwitch (accessible via the Details class) complements magically the standard tool set and opens a wealth of things when you leave the path of simple on the outside and step into the richness of the inside.

Unfortunately, it’s weakly typed, which means… magic strings.

What’s the problem?

I came accross an example in my previous post on protecting read-only fields:

partial void Customers_Updating(Customer entity)
        {

            if (((entity.Details.Properties["ChangedBy"]) as IEntityStorageProperty).IsChanged)
            {
                throw new Exception("The changedBy field should not be changed...");
            }
...
        }

So, our magic string is here “ChangedBy”, which refers in fact to the ChangedBy property of our Customer Entity. No problem as longs as the ChangedBy property doesn’t change name. But if the name changes, we’ll run into trouble and we don’t get a compilation error. No good !

Wouldn’t it be great if we could access the “ChangedBy” property in a strongly typed way ? For example as follows:

string changedByProperty = entity.GetEntityObjectPropertyName(c => c.ChangedBy);

            if (((entity.Details.Properties[changedByProperty]) as IEntityStorageProperty).IsChanged)
            {
               ...
            }

How?

Simply add following extension method class to your server side project (if you need it client side, simply add the same class as a file link to the silverlight client project):

public static class IEntityObjectPropertyHelper
    {
        public static string GetEntityObjectPropertyName<TSource, TProperty>
            (this TSource source,
            Expression<Func<TSource, TProperty>> propertyLambda) where TSource : IEntityObject
        {
            MemberExpression member = propertyLambda.Body as MemberExpression;
            if (member == null)
                throw new ArgumentException(string.Format(
                    "Expression '{0}' refers to a method, not a property.",
                    propertyLambda.ToString()));

            PropertyInfo propInfo = member.Member as PropertyInfo;
            if (propInfo == null)
                throw new ArgumentException(string.Format(
                    "Expression '{0}' refers to a field, not a property.",
                    propertyLambda.ToString()));

            return propInfo.Name;
        }
    }

Conclusion

That was easy. In part 2 of this series something more ambitious: we will provide a solution for accessing choice lists values in a stringly typed way.