Aaron Powell's blog

var blogs = umb.Posts.Where(p => p.Intelligent);

Dealing with type casting limitations

Friday, 27 November 2009 by Aaron Powell

Well this is the first post involving the .NET 4.0 framework, woo :D.

Something I've had a problem with from within the abstract service lay which we use at TheFARM.
It's a limitation of the .NET framework and how you can do type casting within the .NET framework.

The way we use our service layer is to never return classes, we only return interfaces, so you can't write a method which looks like this:

public IEnumerable<IProduct> GetProducts() { 
  return ctx.Products.AsEnumerable();
}

This will throw an exception, even if the class Product implements the IProduct interface. To achieve it you need to do this:

public IEnumerable<IProduct> GetProducts() { 
  return ctx.Products.Cast<IProduct>();
}

This is a bit of a pain if you're doing complex type conversion though, particularly with our LINQ to Umbraco framework (not the actual LINQ to Umbraco framework coming in Umbraco 4.1).
The problem really came up when I decided I wanted to change from using a constructor which takes an XElement, so you could write cleaner code like this:

public IEnumerable<IUmbEvent> GetEvents() 
{ 
    XElement xNode = UmbXmlLinqExtensions.GetNodeByXpath(EventContainerXPath); 

    var eventData = xNode 
        .UmbSelectNodes() //selects all descendant "node" nodes 
        //selects nodes of a certain alias 
        .UmbSelectNodesWhereNodeTypeAlias(EventNodeTypeAlias) 
        //This does the object conversion 
        .Select(x => (UmbEvent)x) 
        //ensure we don't return events with no start date 
        .Where(x => x.FromDate != DateTime.MinValue); 

    return eventData.Cast<IUmbEvent>(); 
} 

Still we're doing a Select and a Cast, since now I've got an explicit operator defined for doing the conversion between XElement and UmbEvent, so I thought, why can't I just do this:

public IEnumerable<IUmbEvent> GetEvents() 
{ 
    XElement xNode = UmbXmlLinqExtensions.GetNodeByXpath(EventContainerXPath); 

    var eventData = xNode 
        .UmbSelectNodes() //selects all descendant "node" nodes 
        //selects nodes of a certain alias 
        .UmbSelectNodesWhereNodeTypeAlias(EventNodeTypeAlias) 
        //This does the object conversion 
        .Cast<UmbEvent>() 
        //ensure we don't return events with no start date 
        .Where(x => x.FromDate != DateTime.MinValue); 

    return eventData.Cast<IUmbEvent>().ToList(); 
} 

But alas that wont work, due to the way the Cast<TResult> method works it's not possible, very annoying.
So I can't directly return a collection of types which implement the required interface, and I can't use the Cast method to just do all the conversions, I have to write select methods.
This just means I have a bunch of code smell, it's not really causing any problems, it's just ugly. I do love some clean code, and this isn't really it :(

So I thought, why not write my own extension method to do the casts, something that has a return statement like this:

yield return (TInterface)(TType)item;

Assuming that TType inherits TInterface, you can write generic constrictions which handles that, but you will receive a compile error, it can't be confirmed by the compiler that the type of item implements an explicit operator to cast it as TType.

Damn, looks like we can't do it with .NET 3.5.

Enter the world of .NET 4

So I decided to see if I can actually achieve it, no matter what was required, but I didn't want the code to look too terrible.
As I'm sure you're all aware .NET 4.0 is bringing in a new keyword, dynamic, which then in turn works with the DLR to do the runtime operation. And you know what, we can leverage the runtime feature to delay the conversion.

Lets have a look at the extension method, and then we'll break it down:

public static IEnumerable<TInterface> AsType<TType, TInterface>(this IEnumerable source)
    where TInterface : class
    where TType : TInterface, new()
{
    if (!typeof(TInterface).IsInterface)
    {
        throw new ArgumentException("TInterface must be an Interface type");
    }

    foreach (var item in source)
    {
        dynamic d = item;
        yield return (TInterface)(TType)d; 
    }
}

So I've got an extension method which has 3 types in it:

  • Type for the collection items
  • Type of the class
  • Type of the interface

I'm doing a check of the TInterface type to make sure it is an Interface, if it's not then we'd have a problem :P

The really exciting part is this:

    foreach (var item in source)
    {
        dynamic d = item;
        yield return (TInterface)(TType)d; 
    }

Here we enumerate through our collection, but turn each item into a dynamic version! This means we can then do the complete type conversion and delay its evaluation until runtime!
Woo! Now I can have code like this:

IEnumerable<int> numbers = Enumerable.Range(0, 10);
IEnumerable<IMyType> casted = numbers.AsType<MyType, IMyType>();

Sweet, now I can make my service method like this:

public IEnumerable<IUmbEvent> GetEvents() 
{ 
    XElement xNode = UmbXmlLinqExtensions.GetNodeByXpath(EventContainerXPath); 

    return xNode 
        .UmbSelectNodes() //selects all descendant "node" nodes 
        .AsType<UmbEvent, IUmbEvent>()
        .Where(x => x.FromDate != DateTime.MinValue); 
} 

So pretty, I'm much happier... well once I can get to use more .NET 4.0.
Oh, and yes, there is a performance hit for this, since we're using the DLR the conversion is evaluated at runtime, not compile time. It's probably not huge (I didn't do any performance testing), but just something to be kept in mind.

Comments (0) |  Generic .NET .NET 4 Perminate Link

Why I'm not a fan of XSLT

Wednesday, 4 November 2009 by Aaron Powell

When I first joined the Umbraco team with the goal of bringing LINQ to Umbraco to the core framework there was some excitement and quite a bit of the early excitement was from Umbraco MVP Warren Buckley.
And with the recent beta release the focus has come back onto LINQ to Umbraco, myself and XSLT.

While preparing to write this post I was tossing up with the name. Although I've entitled it "Why I'm not a fan of XSLT" it would have been just as apt to name it "Why write LINQ to Umbraco?".

As you read through this post I was you to keep in mind that I'm not someone who is really that good at XPath and XSLT. In fact, my dislike for XSLT is why I wrote LINQ to Umbraco!

But why, being an Umbraco user, don't i like XSLT? After all, it's a fairly core part of Umbraco!

Compile time checking

That's right, I'm very much a developer, and very much a compiler-driven developer. Runtime errors really are the worst to try and debug, and that's what you really get with XPath. XPath is evaluated at runtime (yes, that's a bit generalized :P), so if you have something wrong in your syntax you wont find it immediately.

Compare that to .NET code, it's very hard to write .NET code which wont compile. True that you can still get runtime errors, but they are a lot harder to achieve in the scenario's we're looking at for LINQ to Umbraco vs XSLT.

Strong typing

Again, another example of me being very much a developer, I would much rather look at an object with properties which knows of the type of the data.

If you're not careful you can mistake the type and then you, again, have a runtime error :P.
The .NET compiler wont let you assign a string to an int.

Readability

This one will cause a bit of a stir, but I simply don't find XPath & XSLT readable. Take these two examples:

//node[nodeTypeAlias='home_page']/node[nodeTypeAlias='contact_us' nodeName='Contact Aaron']
ctx.HomePages.ContactUs.Where(c => c.Name == "Contact Aaron");

My example is very basic, but if you look into a more complex XSLT file (such as many which exists in Warrens CWS package). In fact, in the unit tests for LINQ to Umbraco there is a replication of a few of them (have a look in the source on Codeplex if you want to see them).

A very important component of code for me is readability. When debugging, especially if the code isn't yours to begin with, readability is a vital component. You don't want to have to waste time trying to understand what's going on in the code before trying to solve it.
And if you can't work out the code properly then there's a chance you'll just make the problem worse.

API Design

Again I'll probably cause a stir with this one again but it's another thing that is very dear to my heart. I am a strong believer in proper API design, and if it's done wrong then it can make your life hell in the future.

I also like abstractions. LINQ to Umbraco is an example of that... provider model! Here at The FARM we've got a great level of abstraction which we use, we don't pass classes around, only interfaces, which means that your UI is dumb, really really dumb.
There isn't any business logic contained there, and there's nothing more complex than a method call.

But too often when I see an XSLT it's containing more than just UI code. And this isn't really a fault of XSLT, but of how it's perceived. When you look at an ASPX/ ASCX people have a different mindset, you don't put anything really in the front-end file other than the markup as there is a CS file associated which you think to put the other complex code into.
But with an XSLT there isn't another file, so everything ends up there.

Then it becomes too complex to try and achieve with XSLT *cough variable incrementing cough* so an XSLT extension is written. And I've seen some really scary XSLT extensions, which allow you to do things which just make me want to cringe.

XSLT should only be concerned with formatting data to output markup...

XSLT's produce better markup

Anyone who says that is ill-informed. If you don't think you can write valid, XHTML markup with ASP.NET Web Forms then you're not doing it right!

Control Adapters, Repeaters, List View, inline script blocks, etc can all be used to produce what ever markup you so desire.
And it doesn't take much effort to produce good markup with ASP.NET. In fact, with Visual Studio 2008 it's really hard to use the standard editor to produce crappy markup.

The biggest problem is ID's of elements, but you only have that problem if the element is:

  • Inside a naming container
  • Set to runat="server"

And you should only be setting runat="server" on elements you need server-side access to, but that's a topic for another night.

 

Conclusion

So this brings me to the end of another post. Hopefully it's been enlightening and I haven't upset too many people :P

Fraternising with the enemy

Monday, 2 November 2009 by Aaron Powell

Disclaimer:

I am not a Sitecore developer, nor have I even used Sitecore. I did use to work with Al Denyes (the Australian Sitecore MVP) and Chris Giddings (who has done a bunch of freaky stuff with Sitecore).

This is from the experience of someone who despite having not used Sitecore I've heard plenty of spiels about it and worked with quite a number of other CMS's.

I'll do my best not to be bias ;)

 

So last Wednesday (28th October) I headed down to the 2nd Sitecore Australia user group. Having attended the first one in Melbourne a few months back (which didn't go so well due to it being held in a pub where you couldn't hear anything) I was interested to see how this went, and to see what was new in Sitecore land.

Sitecore 6.2 was the release focus of the night and it has a couple of new features I want to talk about, from the point of view of a non-Sitecore developer.

 

Microsoft Word Editing

Anyone who was at the UG will have seen me cringe when they started talking about this feature, particularly when it was stated that the MSO tags are kept.

From a technological standpoint I think this is a fascinating feature, but from a web developer I think it's a very scary feature. As someone said to me on the night, "It'd be great for intranets".

But the feature did make me wonder as to why, if people are preferring to work with Microsoft Word than the Sitecore editor (which is the Telerik Rad controls I believe) does that mean the standard editor has deficiencies? 
I've never been a huge fan of Sitecores UI recreation of the Windows UI, but that's another topic on its own.

Basically I see this as a great feature to demo, but the practicalities of it aren't there.

 

Improvements to the Forms Module

A lot of what was talked about here was over my head as I'm not familiar with the campaign manager in Sitecore.

But there is a new feature that caused a bit of a stir, and that is that the forms can be configured to capture the data as a user enters it. Now I can see the goal of this, so you can monitor drop-out rates of your form, but there's a much bigger problem... Privacy.

Take this scenario - I start filling out a form, put in my details (name, phone number, etc) and then get to the privacy policy and decide that I don't agree with their decision to sell it on to anyone who wants it. I decide to exit out of the form.
Little do I know is that the data was already captured. This is rather concerning, I didn't consent to them having it, but they still got it.
And if the company is a bit naughty they may still on-sell my data. All without my agreeing to do so.

I get the point of the feature, monitoring drop-out rates and at what point but I think you may walk into a legal mind field.
Please note though - I'm not a lawyer, but one of the other people at the UG did put the question to a lawyer and said it is a dangerous place to go.

Thankfully you can turn the auto-capturing feature off. Or host your site in like Sweden :P

 

Drag-and-drop Media uploading

The SharePoint implementation is a crap load better :P

 

That's pretty much my highlights of the night (other than the fact that I scored a bunch of free Sitecore mouse mats... Anyone want a Sitecore mouse mat? :P). I didn't quite share in Tim's enthusiasm for the LED keyboard which they are giving away, it's not a new product Tim, and it would also be rather unpleasant to use I think...
It also doesn't look like I'll be able to keep my 100% track record up with attendance, since the new UG is in Brisbane next year some time :P

Comments (4) |  Umbraco Sitecore Perminate Link

Working with dates and LINQ to SQL

Sunday, 1 November 2009 by Aaron Powell

Something I've heard developers complain about on numerous occasion is that DateTime comparisons between SQL and .NET is a real pain. Often you need to do a comparison of the date against either a Min or Max value.

With raw .NET this is really quite easy, you can just use the DateTime struct and grab DateTime.MinValue or DateTime.MaxValue.

But if you've ever done this:

var res = from item in Collection where item.CreatedDate != DateTime.MinValue select item;

You'll get the following exception thrown:
SqlTypeException: SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM.

The problem is that DateTime.MinValue is actually 1/1/0001 12:00:00 AM.

So I've quite often seen hacks where a new date is being created which represent the minimum value of the SQL server, and all kinds of weird things, but that's all redundant.
The comparision value is built into the .NET framework.

All you need to use is System.Data.SqlTypes.SqlDateTime structure. This exposes two fields, MinValue and MaxValue. All you need to do is access the Value property of these and pass it into your LINQ statement.
The date will be parsed correctly as a SQL valid date and you can do your comparisons!

So please, stop with any silly workaround for date comparisons with SQL and .NET :P