Progressive Digressive Marcus Whitworth's tech blog – .NET, C#, Silverlight, WPF, Flex…etc, etc

2Dec/092

Dynamic Linq with Expression Trees

I recently came across a project requirement for the client to create custom validation rules for retrieving data from the SQL database. The rules needed be applied against any number of member applications, and can be altered by the client at any point.

From the client perspective, the administration of the rules would look something like the following:

Rules Administration

Simple enough concept.  Historically, given such a requirement, you'd likely end up with some fudged SQL string (if querying a database), and/or a whole lot of conditional logic.  The application already uses Linq2SQL, so I didn't want to go backwards by introducing some extensive SQL string generation.

The first Linq based option I came across was the Dynamic Linq Query Library, which essentially enables you to use SQL-like strings as expressions in your conditional clauses.  Nice, but it still smelled a bit like the SQL string concatenation of old.

The second option I looked at was PredicateBuilder.  It's a neat solution for the right problem, but it assumes that you know the properties/columns you're querying against at compile time.

So, I decided to have a play around with Expression Trees, in an effort to dynamically generate my conditional expressions at runtime.  I hadn't really delved much into this area before, so I figured it'd be a good learning experience, even if it didn't end up working out.  To cut to the chase, the method I ended up with for parsing my rules into Lambda Expressions looks like the following:

public static Expression<Func<T, bool>> GetExpression<T>(
	string propertyName, string operatorType, string propertyValue)
{
	var isNegated = operatorType.StartsWith("!");
	if (isNegated)
		operatorType = operatorType.Substring(1);

	var parameter = Expression.Parameter(typeof (T), "type");
	var property = Expression.Property(parameter, propertyName);

	// Cast propertyValue to correct property type
	var td = TypeDescriptor.GetConverter(property.Type);
	var constantValue = Expression.Constant(td.ConvertFromString(propertyValue), property.Type);

	// Check if specified method is an Expression member
	var operatorMethod = typeof(Expression).GetMethod(operatorType, new[] { typeof(MemberExpression), typeof(ConstantExpression) });

	Expression expression;

	if (operatorMethod == null)
	{
		// Execute against type members
		var method = property.Type.GetMethod(operatorType, new[] {property.Type});
		expression = Expression.Call(property, method, constantValue);
	}
	else
	{
		// Execute the passed operator method (e.g. Expression.GreaterThan)
		expression = (Expression) operatorMethod.Invoke(null, new object[] {property, constantValue});
	}

	if (isNegated)
		expression = Expression.Not(expression);

	return Expression.Lambda<Func<T, bool>>(expression, parameter);
}

Which can be executed with a call like the following:

foreach (var rule in rules)
{
	applicants = applicants.Where(
		GetExpression<Applicant>(
			rule.MemberName, // The Applicant property
			rule.Operator, // Equals, Contains, GreaterThan, etc
			rule.Value)
		);
}

The rules are looped over, and Linq does its magic by combining all the separate rules with AND statements in the resulting query.

A few things to note:

  • Operators are just the method names to be called, against the Expression type, or any other CLR or custom type.  If you put a ! in front of the operator, it negates the method result (!Contains would read 'Does Not Contain').
  • Reflection isn't necessary for building an expression, I just use it here to enable runtime operator implementation, against both the Expression class and potentially any other class.
  • If you wanted to combine your rules with OR statements, it could be done easily enough with logic similar to what PredicateBuilder uses.
  • There is possibly/probably better ways to do this - if you know one, speak up!

Is this necessarily any better than using the Dynamic Linq library?  A bit - it doesn't really give me any compile-time type safety benefits, but I could potentially handle certain exceptions that I perhaps wouldn't be able to detect using Dynamic Linq, such as casting the value to the correct type.  On top of that, I like it more, it feels more robust, and doesn't require external libraries to work.  If nothing else, it gave me an excuse to get my head around some lower-level Expression Tree stuff :)


Kick It on DotNetKicks.com

Post to Twitter Post to Yahoo Buzz Post to Delicious Post to Digg Post to Reddit Post to StumbleUpon

13Oct/090

ReSharper 5 – and I thought 4 was good

Reading this preliminary list of the upcoming features of ReSharper 5, it makes me wonder how any .NET developer could ever be without a tool like this.  Among the favorites would have to be Project Refactorings, and Call/Value Tracking.  Genius.

Having used the refactoring-and-[insert feature here]-anaemic Flex Builder 3 at length on a few recent projects, life just seems to get better and better in Visual Studio land.


Kick It on DotNetKicks.com

Post to Twitter Post to Yahoo Buzz Post to Delicious Post to Digg Post to Reddit Post to StumbleUpon

24Sep/090

Creating a custom Silverlight 3 Smooth Streaming player

When it comes to video delivery, I come from a Flash background.  I've worked on numerous streaming video projects over the years, all of which were created with Flash & Actionscript on the client side. Having been through the process several times, I know all the hurdles I'm going to have to clear well in advance.

Documentation for coding a Silverlight 3 player against IIS Smooth Streaming is a little sparse.  IIS.net has several articles on the server setup, but I couldn't find anywhere obvious regarding the client connection.

Unlike progressive video playback, you can't just point the MediaElement.source at the video path then call play().  After a bit of searching, most people were talking about some AdaptiveStreamingSource class, which isn't available in the base SL toolkit, but rather only found in SmoothStreaming.dll within the template players generated from Expression Encoder!

Per some handy forum posts, the steps required are:

  1. With Expression Encoder installed, go to C:\Program Files\Microsoft Expression\Encoder 3\Templates\en, select any template, and copy the SmoothStreaming.xap file.
  2. Rename your copied .xap file to .zip, unzip, and take out the SmoothStreaming.dll and PlugInMssCtrl.dll files.
  3. Reference these assemblies in your project, and you can then start using AdaptiveStreamingSource.

So, once you can finally access the required assemblies, you can then invoke your IIS Smooth Streaming service with something along the lines of the following:

var mediaPath = "testClip_h1080p.ism/manifest";
var source = new AdaptiveStreamingSource
{
   ManifestUrl = new Uri(mediaPath, UriKind.RelativeOrAbsolute),
   MediaElement = streamElement // the xaml MediaElement
};
source.StartPlayback();

Make sure you put the trailing '/manifest' after your stream path.

Simple enough, once you've figured out the basics! Not exactly sure what MS were thinking by not including the SmoothStreaming assemblies in the SL3 toolkit? Surely they realise not everyone wants to use a templated player. Or have I missed something here?


Kick It on DotNetKicks.com

Post to Twitter Post to Yahoo Buzz Post to Delicious Post to Digg Post to Reddit Post to StumbleUpon