Pixata Custom Controls
For Lightswitch

Recent Posts

Popular tags (# posts in brackets)

Anonymous types (3) ASP.NET (5) C# (3) C# tricks and tips (2) Computers (6) Design patterns (3) DomainDataSource (3) Dynamic data (4) Entity framework (3) Entity model framework (5) F# (3) LightSwitch (12) Linq (6) Microsoft (2) MVP (2) MVVM (2) Project Euler (2) RIA services (5) Silverlight (2) SQL Server (4) Unit testing (4) Visual Studio (7) WCF (3) WPF (3)

Gratuitous link to StackExchange




The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

Actually, as I'm self-employed, I guess that means that any views I expressed here aren't my own. That's confusing!


Theme modified from one by Tom Watts
C#/F# code styling by Manoli (for posts pre-2016) and Google code prettify (for post from Jan 2016 and beyond)

My rambling thoughts on exploring the .NET framework and related technologies

A problem with anonymous types

One of my first posts on this blog was about the problem of using anonymous types when you want to send the data outside of your current class. At the time, the only way I knew to solve this was to create a simple class that had the structure of the anonymous type, and create one of these instead of the anonymous type. I do this regularly, although I have taken to naming such classes CustomerOverview, OrderOverview, etc, instead of CustomerTmp as I did in that blog post, as they aren't really temporary classes at all, they are slim, flattened overviews of the class.

This approach works well, but it can have its downsides. One, as mentioned in that post, is that it is easy to end up with a proliferation of classes, many of which may only be used in one location in the code. If the classes represent lightweight views of entities in the model (such as the two examples shown above), then I don't worry about this, as it is clear what they represent, and it's fairly certain that I'll end up using them somewhere else at some point.

However, the problem does become more apparent when the classes are very specific to one part of the code. I feel uncomfortable having classes that don't really represent anything in the object model as a whole. Granted, this isn't a very common scenario, as if your code is structured sensibly, you will probably find that you don't have these artificial classes, but it is something that happens every now and then.

For some odd reason, I was struck with an idea whilst I was washing my face the other morning! Now why this would pop into my head at 6am, when I hadn't even thought about the issue for a year or so is beyond me, but I don't claim to understand the workings of the human mind, especially one that is bleary from lack of sleep!

A little-known, but intriguing class

One of the less-known and more interesting (but ultimately useless in my experience) additions to the .NET framework version 4 was the Tuple class. This generic class allows you to create an object that consists of up to eight pieces of information of a specified type (Note: the slightly arbitrary reason why they picked eight as the maximum can be found in this MSDN Magazine article).

As an example, suppose you want to get a list of customer names and database IDs, but don't need any of the other information in your customer entity. Instead of creating a CustomerOverview class, you could just create a Tuple<int, string> which would hold the two pieces of information. Thus, you may have a method with a signature like...

  public List<Tuple<int, string>> GetCustomerIdAndNames() {
    List<Tuple<int, string>> customers = new List<Tuple<int, string>>();
    // In reality, this would be populated from a database...
    customers.Add(new Tuple<int, string>(1, "Fred"));
    // etc...
    return customers;

So far so good. All of this looks jolly useful eh? So why did I describe it as ultimately useless? Only because my few experiences with using the Tuple class have ended up with changes in the requirements, which meant that every bit of code that used the Tuple had to be changed, at which point it became clear that it would have been much better design to have used a WhateverOverview class in the first place. So, whilst it's an interesting addition to the framework, it's one that I have never actually used (for very long anyway).

All that changed at 6am the other day. I had a flash of inspiration, which can be quite unnerving at that time of the morning!

Binding ASP.NET Repeaters to collections of Tuples

The issue I had that prompted that old blog post was sending data to an ASP.NET page, where it would be rendered using a Repeater control. For those of you not familiar with ASP.NET, this server-side control allows you to display a collection of items on a web page, without having to write all the code to loop through the collection and render it yourself. You just set up a simple template, bind the collection to the control, and the ASP.NET rendering engine does it for you. Now, those masochists who like writing everything themselves (such as those who use ASP.NET MVC!) might turn their noses up at such ideas, but as a professional ASP.NET developer for many years, I rely on controls like this to help me work more quickly. Microsoft provide a robust and efficient way of doing a job, why should I ignore it and do the whole thing by hand?

Anyway, the problem comes when you want to pass a collection of anonymous types to a Repeater. As the rendering engine needs to know the of each item in type of the collection, so that it can handle it appropriately, you can't bind a collection of anonymous types to a Repeater. So, to continue my earlier example, if you want to use just the customer ID and name in the Repeater, you either have to send across the whole Customer entity (which may involve a large amount of unneeded data), or create a CustomerOverview class, and pass a collection of those.

In this case, a customer is a logical enough entity that you might want to create the CustomerOverview, but there are many cases where you wouldn't. The specific collection of data items you want may be unique to this view, and creating a custom class for it would pollute the overall object model.

The simple answer to the problem is to generate a collection of Tuples, and pass that to the Repeater. As the Tuple is a known class, and the instance of it is strongly-typed, the ASP.NET engine won't have any problem with it at all, and can happily render the data without the need for an overview class.

A fairly simple answer, using a class that turned out not to be so useless after all!

A caveat

I would be remiss if I didn't end off with a comment about this approach. Although it works, and neatly solves the problem, I have to say that I'm still not a huge fan of using Tuples, especially when they are going to be passed outside of the class in which they are created. The reason is simply as I stated above, that requirements change, and if you find the need to change the length of the Tuple, or change the type of one of the items, you end up having to modify code in multiple classes. This gives the very strong feeling that you're working with strongly-coupled code, which is never a good idea.

Having said that, many times when you pass a collection to a Repeater, you don't actually need any code in the ASP.NET code-behind, as most of the data binding can be done automatically, so you probably don't need any code in the code-behind that is specific to the Tuple in question. Therefore, if you change the Tuple where it is generated, you won't need to change anything in the ASP.NET for it to continue working. This is especially true if you are using MVP, where the presenter can take care of any formatting that you want on the data items. In a case like this, I would be happy to use Tuples.

Phew, that was quite a lot of thought for first thing in the morning!

Friday, 04 November 2011 12:09:00 (GMT Standard Time, UTC+00:00)

Always on the lookout for ways to improve my coding efficiency, I was very interested to hear about WebFormsMvp, which is a framework for writing ASP.NET web sites, based on the MVP design pattern. This post describes my initial frustrations, and eventual delight in using the framework.

In a future post, I intend to describe how to get going with WebFormsMvp, as well as how I extended it to reduce the boilerplate code even more.

Monday, 11 July 2011 16:03:00 (GMT Daylight Time, UTC+01:00)

Avid readers (if there are any!) may remember my recent post in which I extolled the virtues of the DomainDataSource control, and how it enabled us to use RIA services in ASP.NET sites. Well, having bashed my head against the wall for a week or so trying to get RIA services working with ASP.NET, I have decided that the support for this is actually quite limited, and not enough to make it a viable option.

This post gives more details of my exploration, discoveries and eventual disappointment at the conclusion.

Tuesday, 12 October 2010 15:48:05 (GMT Daylight Time, UTC+01:00)

Well, having posted about my excitement over discovering ASP.NET Dynamic Data (ADD), I spent the last couple of weeks digging deep into it, and have eventually come to the conclusion that it was a great idea, but ultimately of little use. I mentioned a few misgivings in that previous post, and I've added a few more to the list. All in all, I don't see me using this technology much.

Having spent so much time on it, I had about ten blog posts in my head, explaining what I'd learnt, but I guess they stay in the recesses of my mind until they fade away into synaptic relapse.

This post explains why I'm moving on.

Sunday, 19 September 2010 15:40:07 (GMT Daylight Time, UTC+01:00)

As I mentioned in my post about the DomainDataSource control (DDS), the same RIA services toolkit that provides the DDS also supplies a validator control called the DomainValidator. As this provides such a useful piece of functionality so easily, I thought it was worth a quick post about it.

Using the DomainValidator control, you can add validation to your ASP.NET pages really quickly and easily, and preserve the n-tier structure of your application - something you coudln't do with the regulat ASP.NET validators.

Wednesday, 18 August 2010 15:53:40 (GMT Daylight Time, UTC+01:00)