Cargowire .NET Articles http://cargowire.net/articles Articles By Craig Rowe Sun, 09 Mar 2014 22:00:00 GMT http://cargowire.net en Programming with circles http://cargowire.net/articles/trigonometry http://cargowire.net/articles/trigonometry Craig Sun, 09 Mar 2014 22:00:00 GMT Fun with the html canvas Sometimes it's fun just to code for the hell of it. Not for work, or a product or some greater aim, just to do something that interests you... So I thought it may be run to revisit some high school maths... obviously.

This article is a mix of a trigonometry primer and some general fun with HTML canvas. The javascript is available in the source (and on github) to see but is certainly not optimised or 'production ready' it's just here to detail the small amount of maths I delve in to, run the demos and act as a kickstarter for you.

As I'm sure you'll all remember from GCSE maths, trigonometry is the study of triangles. In the above diagram we can see the classic SOH CAH TOA mnemonic with the appropriate right angled triangles drawn. To use this mnemonic we must remember the following multiplication diagram:

Fig 1.2: Multiplication diagrams.

To calculate the length of the opposite side (Opp or O) we can use a calculator to multiply the Sine of the lower left angle by the Hypotenuse (Hyp or H). If we had the Opposite but we wanted the Hypotenuse then we would divide the Opposite by the Sine of the angle. Equally if we had the Hypotenuse but we wanted the Adjacent (Adj or A) we could multiply the Cosine of the angle by the Hypotenuse.

As an example: In the SOH CAH TOA diagram (fig1.1) the adjacent is 100 wide and the angle is 45°. In Javascript we can do the following:

var hyp = 100 / Math.cos((45).toRad()); // Outputs 141.4213562373095 console.log(hyp);

An aside: Radians

The toRad() function is required because the sin/cos/tan functions in javascript take the degree in radian units. A complete circle angle contains 2π radians (a value which we know as 360 degrees) meaning:

Radians to Degrees and back
2π radians = 360 degrees
π radians = 180 degrees (dividing both by two)
1 radian = 180/π degrees (dividing both by π) π/180 radians = 1 degrees (dividing both by 180)
myRadians * (180/π) = degreesmyDegrees * (π/180) = radians

Triangles as part of a circle

The following diagram attempts to show how useful triangles are when we are working with circles:

Click to pause/play
  • Adj = Cosθ * Radius
  • Opp = Sinθ * Radius
  • X = Circle Centre X + Adj
  • Y = Circle Centre Y + Opp

Fig 2.1: Triangles in a circle.

When using a cartesian coordinate system we can use Cosine and Sine to calculate the X (Adjacent) and Y (Opposite) position values. This is because in a circle we always know the radius (which in the formulae we can substitute as the Hypotenuse) and our desired centre point (which we use as an offset to the Adjacent and Opposite to calculate the final x/y).

Html canvas allows us to draw lines from x/y to x/y and rectangles with a width and height at an x/y position. This is exactly how I'm drawing the circle above. Rendering a small rectangle at each X/Y coordinate returned for the 360 degrees in the circle. I've simply abstracted the generation of x/y points into a getCirclePoints function.

Using Triangles to distribute points around a circle

With the above information we can very easily distribute items around a circle. If we want 5 items we simply divide 360 by 5 to find the angle increments we require (0, 72, 144, 216, 288). We then use these angles with Cosine and Sine as above, using our chosen radius size (the hypotenuse), to find the 2D points.

In the below diagram I've simply drawn lines on the canvas from the centre of a circle out to the points calculated in this way.


Fig 3.1: Distributing points around a circle.

Obviously all you need to do to draw this as a polygon instead is to join the points rather than draw out from the centre.

Making this useful

With these points available to us we can draw more than just lines. For example images:

Fig 4.1: Our first carousel.

As the above shows it is also very easy to apply a rotation over time by simply adding an increasing offset to the degrees for each item. So with three images they are first drawn at degrees [0, 120, 240] then [1, 121, 241] and so on in an animation loop.

To assist in this animation I created a small Animation class that wraps calls to requestAnimationFrame (a built in browser function that calls back to your client code at approximately 60fps), shims it for multi browser support and allows the user to specify their own fps within that provided by the browser.

The rotating demo looks a lot like a carousel. However we don't normally view a carousel head on like this. The circle is tilted away from us into the third dimension. This next diagram should explain how we can get this effect:

Fig 5.1: How to tilt a circle.

The dashed line is the screen viewed from the side with the circle of images (green line) flat upon it. We can see how trigonometry can help us to calculate the adjacent length using the hypotenuse. The Adj shown in the diagram is the position of the bottom most point on a circle that has its top rotated back into the screen - but we need to translate all the points.

To do this we need the varying lengths of the hypotenuse for each point in the circle. Luckily we have this - it's the Y value we would have plotted the item on screen with if there were no tilt.

Remember: For an untilted circle the screen top is y position zero and the Screen Bottom is Y = Circle Diameter. Therefore:

Original 'flat' y offset from the circle centre: yPosition = Math.sin(DegreesAroundCircle) * Radius(Opp = Sinθ * Hyp)
Foreshortened y position: AdjustedYPosition = Math.cos(DegreesTilt) * yPosition(Adj = Cosθ * Hyp)
Final plot point:Circle.CentreY + AdjustedYPosition

Fig 6.1: Tilted circle.

With this tilt knowledge in place we can relatively easy tilt the original basic circle information diagram.

Z Scaling

The above will give us a carousel where the plotted images take into account a tilt away from the viewer. This is fine for a line/point diagram however to give the impression of the images on a carousel moving into the third dimension we need to scale the items in the distance. This can be achieved very simply by identifying the Z axis depth as a percentage of the diameter. At 0 we use the maxmimum scale and at 1 we use the minimum scale with proportions in between.

By drawing the items to the canvas in the correct z-order we then get the appropriate overlap. Maintaining objects with a z-index also assists us in hittesting items if we start to detect mouse events.

The tilted carousel

Fig 7.1: A tilted carousel.

The closer the angle gets to 90° the more the carousel looks like cover flow.

Getting fancy

With these basic steps in place we can begin to add adjustments to the values. If you've been looking at the javascript code as we've gone along you may have noticed that I pass a 'yAdjustmentFunc' into a few of the functions. This is to allow me, after I've calculated the intended canvas x/y, to apply some kind of variance to the position based on the angle.

For example the below carousel displays an additional y adjustment based on a Sine Wave (and it changes the pictures.. because.. why not).

Fig 8.1. An actual carousel (Horse image from HBruton's profile on Deviant Art)

Conclusion

Hopefully this has been a whistle stop reminder tour of some very simple mathematics. Certainly if you wanted to do complete interactive 3D you may prefer WebGL and manipulating points/vectors is often done with matrix transformations.

This was purely an exercise in taking a simple piece of geometry and slowly developing it into something a little more complex.

N.B. Sine Wave

You may have heard people talk about Sine Wave's and not fully understood the meaning. It relates to a regular up and down wave form that can be mathematically calculated using the sine of an ever increasing angle. Note in the diagram below that the Y position of the wave is tracking the y position of the point at the end of the drawn radius.

Fig 9.1: A sine wave explained.

]]>
Code review http://cargowire.net/articles/codereview http://cargowire.net/articles/codereview Craig Mon, 04 Nov 2013 21:00:00 GMT More knowledge sharing Having written last about knowledge sharing I almost immediately wanted to get some thoughts down about code reviews. In the back of my mind during that post I was mulling over the idea of serendipitous knowledge sharing, or at least knowledge sharing that isn't of the standard documentation style (wiki, issue tracking, code comments). And so... Code Reviews!

It's hard to recommend, encourage or enforce team members to keep abreast of latest wiki posts because it doesn't fit into the usual flow of work. Yes they are absolutely necessary and useful but they are often more go-to reference rather than regular read. This may be less so if a more story telling style blog is also available but it's hardly something you'd list in your standup as a task for the day "oh yes and I'm going to read the company blog".

So if we look at a 'standard' day for a dev team member it might include a standup, writing some code on your current task, possibly helping out a colleague or maybe doing some research or breaking down some requirements for an upcoming project. Where in there can we get some cross team knowledge sharing? well, short of pair programming the only place is when you're helping someone else with a problem. But that is less controllable and often relies on proximity, friendships and people who consider themselves most available.

Endorsed code conversations

This is where code reviews come in. I'm sure you've done or are doing code reviews. To be honest I'd like to rename them 'code conversations'. Not just because, in a touchy feely way, I don't want to be combative (although that is a valid reason) but because I want to reassert the focus.

What code reviews should not be:

  • A formality
  • A means to fill in copious amounts of forms or spreadsheets
  • A point scoring mechanism to lord it up over your colleagues
  • A metric generator for who's best at writing code 'first time'
  • A laborious process of checking against a style guide - this should, if done at all, be done by automated tools such as StyleCop.

Remember: My problems understanding your code are rarely to do with whether you put opening brackets on one line and far more likely to do with your overall design. Yes, if it's awfully laid out it will make it harder, but perfectly indented, capitalised and bracketed CRAZY-ASS code is still crazy code. Death by a thousand cuts is a possibility but it's avoidance isn't the end goal of a code review.

Code reviews should:

  • Be Collaborative
  • Provide a guaranteed, regular timeslot for the discussion of code
  • Become one of the means by which you organically permeate knowledge and consistency across the team
  • Be a way of injecting a social aspect to a work related activity

Code reviews should be a discussion (whether they are done in person or remotely). Crucially they are a discussion regarding an artefact, unlike design meetings or sprint planning there is a 'thing' that is the product of constraints, newly identified knowledge and a whole number of cumulative decisions. There's a lot of scope in that to get into some detailed worthwhile discussion.

In fact if you've learned nothing from a code review you're either a liar or you did it wrong. Now, what you've learned could range from a specific new programming technique to knowing more about a client you are yet to work for. It could even simply lead to you knowing one of your colleagues a bit better - which is definitely still a good thing if it helps next time you need to collaborate.

I'm not saying code reviews negate the need for design discussions or even pair programming. But code reviews are held in the cold hard light of day, objectively and ideally with a fresh set of eyes that wasn't involved in the design or coding. The aim is to remove bias and ego from the equation.

A quick note on style guides - although coding style guides don't just focus on syntax, if you've got a mature team and still need a style guide document that is referred to in code reviews then it's probably a warning sign. Focusing on syntax is the easy way out/lazy mans code review which should, if at all, be completely automated.

I haven't got all day

I'm not saying that this enforced rubber duck programming should be days long and lead to the entire codebase being rewritten but it can, and maybe should, lead to some refactoring notes or tasks. It's never 'too late' for feedback from review. Afterall your team is constantly learning, growing, evolving isn't it?

Code Review isn’t just useful for finding defects. It’s a great way to spread information about coding standards and conventions to others as well as a great teaching tool. I learn a lot when my peers review my code and I use it as an opportunity to teach others who submit pull requests to my projects. Phil Haack (emphasis mine)

If it helps, think of it as avoiding a build up of knowledge debt.

Process

Now, although I've used 'enforced', 'regular' and 'guaranteed' up to this point 'code conversations' can still be rather informal and don't have to lead to, nor should, generate reams of paperwork. Documenting counts of 'issues found' as part of a code review is only useful if you intend to use it as a stick to beat someone with - and hopefully you've got better processes in place to review performance including peer involvement in staff review meetings.

I'm not a huge fan of 'gated checkins' however it can be useful to hook into the tools that your source control provides such as using 'pull requests' as the instigators of a code review. These are especially useful if you are only able to complete a code review remotely. The pull request will become the shared notepad for your dialogue but should be part of a process that includes direct discussion. The key is to avoid moving through a commit history one file at a time (often in changed, or worse, alphabetical order) as this encourages a focus on the minutia.

No-one is above the law

I Am the Law!

If we treat code reviews as code conversations we're effectively removing seniority and absolute correctness from the equation. That is to say we enter them on equal footing both trying to make the code and our understanding of it better. If that's the case there's no reason why anyone within the team should not be subject to the code review process. A junior forcing a senior to explain something is just as valid and useful as a senior pointing out an error in a juniors work (and that isn't even allowing for the possibility that the junior, by questioning the dogma of a senior assists in a breakthrough for both).

But I work alone

The social aspect of code review's is a big plus. If you're working on different projects or 'in the zone' on your own code it can be easy to fall into going most of the day without really getting involved with your colleagues. Being asked to code review breaks that up a bit while avoiding the possibility of getting swept up in a crazy idea as you egg each other on during pair programming (by the way, I don't think pair programming is bad because of this but it is a plus point in the favour of post-coding reviews over sitting together throughout).

As an individual you might be able to rope in a friend from a different company, or a co-working space to help with code reviews. But if you can't you might try out sites like http://codereview.stackexchange.com/. Although in this case I suspect you may wish to be more targetted in the choice of code you submit - unlike within a team when there's no reason that every single line of code should not be reviewed.

So what are Code Reviews really about

Code review's are ostensiby about code quality but they have huge potential to increase team unity, better prepare team members for working across projects and assist in cross polinating skills. It does require effort and a move towards egoless programming but should be easily sellable within an organisation not least because of the surface argument of identifying defects.

As a manager you even get to play god a little bit... encourage team members who you notice don't interact much to get involved with reviews together, ensure that people who've been on individual projects for a long time are assigned to review something wildly different or even get a junior to review some of your code in their first week.

It's also the easiest way to encourage and endorse discussions about code and work projects without sounding like you're trying to get down with the kids "hey guys It's time for show and tell what you got goin' on".

]]>
Knowledge sharing http://cargowire.net/articles/knowledgesharing http://cargowire.net/articles/knowledgesharing Craig Tue, 24 Sep 2013 17:00:00 GMT Arguably the most important thing to get right as a team, whether you are leading it or have just joined it, is how you share knowledge. Without a good strategy you can end up over reliant on long standing staff or worse - alienating new starters.

I hope I don't have to convince you that neither of these are a good place to find yourself as an organisation. Long serving staff may like the idea of being 'unsackable' but the business sure doesn't and the extra stress of always being the only 'go-to' guy/gal is not something to revel in in the long term [1].

Don't think this doesn't apply if you're an independant freelancer. It isn't just people you need to spread knowledge across. It's also time. A year after you did something you may want to reuse it or need to refresh your memory rather than re-learn it.

What is Knowledge?

All I know is that I don't know nothing Operation Ivy

So what are we talking about?

  • Local dev configuration and setup details
  • New technologies and approaches
  • Where to find existing (reusable) code solutions
  • Hosting and access details for projects
  • Particular nuances of project implementations

How do you eat yours?

You've got it in e-mails right? you remember it - I mean, it was only a couple of weeks back? What do you mean you forgot? what do you mean she's on holiday?

Discoverability - Pull vs Push

There're two ways you can spread information within your team - you can push it out to them, or leave it out there ready to be picked up whenever they want or need it, or maybe even when they least expect it. Both push and pull have their merits but I find that just sending e-mails out with links tends to get ignored in the deluge of all other work e-mails.

This is also true of mediums where time effects the findability. I'm thinking here mainly of 'streams' of content such as chat rooms and facebook wall style collaboration applications. Don't get me wrong, the publish date of content is incredibly important in such a fast moving industry but it's better placed as part of the header of the content, or as part of a historical 'version' of that content. Ordering unrelated content based only on the time written is the worst taxonomy. How far back does a viewer go? are they expected to read everything? is your stream poluted with unrelated or extremely transitory content?

Issue Tracking - we need to know when and how we fixed something

Day to day work is probably managed via some kind of task list/bug tracker. I say probably, I mean should be. It doesn't really matter which as long as it's searchable, identifiable (e.g. each task has a short unique url) and maintains its history (comments and status changes). It also needs to have complete visibility within the team. Segmenting access is just hiding potentially useful information from others. Each issue should clearly identify the problem or task followed by any information on what was considered during design or investigation and the final resolution. If possible include either a list of changed files or for extra brownie points have a system whereby issues are associated to actual source control commits.

Being able to search this is invaluable even if you're the one who fixed something. Your notes from the time are going to be far more detailed than your flakey memory. The nice thing about issue tracking knowledge is you can search based on the problem you know you fixed rather than the solution you can't remember.

Wiki

There are two types of information that you might want to store in a wiki. Project documentation, and general documentation. That is to say, meeting minutes, project documents/deliverables are quite different from tips and tricks or hosting details for a particular live site. At Headscape we used Confluence (as part of our JIRA install). In this setup we had wiki's per project that were used for day to day project management and a single central company wiki that contains: a page for each client including hosting and special information (such as accounts or third party tools used), pages for how to use or get up to speed with our internal tools and pages regarding the company such as phone lists.

To reiterate we don't want information stuck in people's heads or e-mail inboxes - and we certainly don't want to be one of those firms that have centralised access to everyones e-mail. No-one should want to be that guy.

If you research something why aren't you writing up your notes in a wiki (even if it's just a page title and a set of categorised links)? if you've figured out a process why can't you just send someone a link when they ask you about it? and seriously, why have you just saved these notes in a .txt file on your desktop?!

p.s. if your wiki pages have few cross-links in them you're doing it wrong... don't lose the potential for serendipitous knowledge sharing!

The Code

Comments

If Wiki's and bug trackers are considered 'par for the course' in a development firm so too is the idea of 'commenting the code'. To be honest I feel like I've gone through a similar process over time as Jeff Atwood has from 'Code tells you how, comments tell you why' through 'coding without comments' to ' learn to read the source luke '. The 'why' is definitely the most advantageous use of comments although the approach discussed by Jeff back in 2008 nails it in terms of the refactoring example removing the need for comments. Patronising comments suck and if a 'Find in all files' search for the words 'sorry' or 'hack' show double figures you should really start worrying about what people are using comments for.

Always keep in mind if you unintentionally or purposefully create an environment where people skip over the comments in your code because they're used to them being either pointless or out of date they're going to do that when/if it ever really matters too. You've just created the flashing banner ads of your codebase. Well done.

Common Code - Reusable libraries

This is far more useful as it is, by definition, the centralisation of other people's learning. If you don't have one please ask yourself why. I've written about this before but there really are many uses of a common code library outside of the oft told reuse/speed gains. Not only do I want to benefit by using my colleagues code I want to revisit their lessons by seeing their implementations, source code commits and potentially related wiki pages. I want to be performing code reviews of projects I don't work on so I can be kept up to speed with them and I want to be able to notice a pothole that I fell into in the past and save them the pain I had.

In my mind Common Code is the best back door route to knowledge sharing. You won't even consciously think you're part of a knowledge sharing solution you're just standing on a bridge built by your colleagues over all the crap they had to stand in.

Company Blogs

Personally I think company blogs are much maligned. The problem is they are all to often a marketing engine. Part of the point of the Headscape Barn site at the time was to try and avoid that feel. In my view a company blog should be more like a magazine with a collective of authors rather than a brochure pushing for sales. The big question then is why should your team blog for the company rather than just on their own sites? well.. for one: it shouldn't be to the exclusion of their own sites. The niche it sits in is being able to be directly about client work (which is often harder on a personal blog without discussion with the client themselves) and done on work time.

When deciding between a wiki page and a blog I like to think of blogs more as telling a story rather than listing cold hard facts.

Company blogs done in this way become a curated written history of project retrospectives.

Personal Blogs / Tweets

To be honest unless you've somehow broken into the big time the audience for your personal site probably goes (in descending popularity order) yourself, people you directly know, occasional google searchers who happen to hit one page. The great thing about them however, is a lot of the time they're something that employees already do (and should be encouraged to do so). You don't need someones job to be to curate and release a weekly 'interesting links' internal mail out - that was and is the twitter streams of your staff (who are also, probably already following each other).

Office setting

The simplest and most powerful knowledge sharing technique (and one I'm sure Marissa Mayer would agree with) is the office setting. Sitting near enough to people that you overhear their cries for help, eureka moments and sliding over on your wheelie chair when you hear "ooo that's interesting". That's not to say homeworking is anathema to knowledge sharing. Daily stand ups and cross team/cross project code reviews can all be achieved remotely.

My Ideal

I quite like the subtle, lead by example approaches of staff twitter streams and common code but the formality of wiki's and issue trackers allow for the full range of 'things I may need to know' on any given day being available without directly having to hassle someone to rack their brains.

The ideal tool is to replace google with a middle man that passes google results through but decorates them with results from your issue tracker, internal wiki and source control. This is a pure pull solution where you don't have to change your instinctive behaviour to jump to google when you hit an issue or have to make a decision.

Don't rely on people's memory, don't expect people to read things when you tell them to, don't silo information away just because it's a different team or project and don't create false settings for knowledge transfer - common code, blogs, code reviews, team rotation are all things you should be doing anyway for a variety of reasons - knowledge sharing being but one of them.

Other options

  • A shared book library
  • Attending hack days and conferences together
  • Show and tells

Footnotes

  1. If you're the guy who likes to hold on to info, safe in the knowledge that you will always be needed, remember, people will work around you. Your knowledge will be replaced (potentially shortly before you are)
]]>
Admit you suck http://cargowire.net/articles/admityousuck http://cargowire.net/articles/admityousuck Craig Sat, 15 Jan 2011 18:00:00 GMT What should be your new years resolution? With the new year upon us I took the opportunity to reflect a little upon my career choice. What would be a good resolution for a developer? ...I decided we should all admit we suck.

Two of my recent articles made subtle reference to this. Within 'common code' I discussed the benefits of knowledge and process sharing, and during my analysis of the 11th Joel Test one of the themes was encouraging a dialog between developers who were both open and equal (i.e. not scoring points smugly).

So yeah, this is going to be a slight rant about humility, 'no man is an island', self-improvement etc but this isn't just to make the world a better place. This has tangible benefits for our careers and happiness.

Benefits?

During the latter part of last year I started collecting quotes from twitter, podcasts and the web in general that related to this idea of admitting you suck. I'll open with one by Scott Galloway:

Bad programmers are the ones who think they're already as good as they can be @scottgal

Let's be clear, we work within one of the fastest moving industries out there. You can literally be out of date on a day by day basis. If you want to get a job, work more productively or even just continue to be supported by vendors you need to stay up to date.

Don't think you're safe in your long service position not looking to move... if you work within a team and a new member joins you want them to be able to take on the work quickly. If you try and mould them to work in a way/with a technology that hasn't been used during their entire working life you are not an attractive prospect for them, and you are adding a large training overhead for yourself.

This doesn't just cover being up to date with technologies. This includes continually improving your own techniques within the existing techs you use. Because, of course, we all have legacy projects, but it's a bad sign if when we go back to these projects we also go back to our mindset at the time they were created.

The supply and demand situation where you're trying to help someone who doesn't want to be helped is not good. "I don't want be better I want to keep sucking..." let them keep sucking. Giles Bowkett

Don't be the person people avoid working with because you aren't open to new ideas or constructive criticism. Don't be precious about your baby. Give it up and open yourself to ideas from others. Acting as if you know best is a sure route to conflict within your team and will gradually isolate you. You're not making yourself a linchpin you're painting yourself into a corner.

The only people who like to hear that their code is bad are those who are trying to be better. Those are the people you want to associate with in the first place. Giles Bowkett

It's important to remember that with the huge variety of tasks/platforms/languages developers deal with every day there is always something you do not know. Length of service doesn't permit you to ignore ideas from newbies. The best quality of a senior is the ability to take something on board and change. It's neither a weakness on their part or a huge victory for you (you're not 'scoring points' by finding a minor error or suggesting a change of direction. You are simply being a good developer).

Refactor!

If you're prepared to admit you're not always right (and have the luxury of time), refactoring code can have excellent results. @jaspertandy

Clients want fast performing, cheap, flexible solutions. They want to know that you aren't stuck in your ways, that you are never resting on your laurels.

Future you wants to be able to thank past you for refactoring code in that legacy project rather than bolting on more and more half arsed patches.

The hard thing here is being willing to admit to yourself that you might have been wrong, or rather that you might now be able to do things better. Don't code in targetted islands. Be willing to reorganise and potentially even do drastic things like delete that chunk of code you just spent hours on but you now realise should be done differently.

More quotes? really?!

The trouble with programmers is that you can never tell what a programmer is doing until it's too late. Seymour Cray

If you put the blinkers on you're likely to make mistakes. The best thing you can do is open yourself up to challenges early on. Fail fast and filter out potential pitfalls by discussing approaches with colleagues or through your blog. You may find you're reinventing the wheel, or making a square one.

Asking someone a question accomplishes far more than just receiving the answer. Robert L Read

In a team dynamic encouraging a culture that doesn't fear being 'wrong' or questionning 'authority' can only be a good thing. It's a classic keep you on your toes scenario.

Ok, I'm done

We, as developers, are living in a world that becomes obsolete very quickly. There's no time for personal pride of the sort that leads you to ignore other peoples ideas or stick with a solution just because it's what you did last time. We need to be constantly checking ourselves.

So I'd say, realise you can't know everything, refactor regularly, start a blog, go to events, encourage code review, discuss your ideas openly, ask for criticism. Because, let's be honest you suck.. and so do I.

]]>
Thoughts on Common Code... http://cargowire.net/articles/commoncode http://cargowire.net/articles/commoncode Craig Sun, 29 Aug 2010 20:00:00 GMT Some ramblings on maintaining a common codebase for web projects including thoughts on the less hyped benefits. As a developer in the web industry you're probably used to buzzwords that seem to get clung on to and overused by non-techs. For me, one of the most oft heard is 'Generic'. An all encompassing word that encapsulates the hopes and dreams of non-techs that as soon as some work is done once, it will never have to be done again and can easily be part migrated into any and all projects, old or new.

Of course, this isn't the reality in a lot of cases, but it should be the gold standard. There's little benefit in constantly reinventing the wheel or working in isolation from the world around you.

What?

So let's start from the beginning... If you're a developer who went the traditional education route you'll be well aware of the idea of reusability.

Reusable code is code that can be used, without modification, to perform a specific service regardless of what application uses the code. http://msdn.microsoft.com/en-us/library/aa189112%28office.10%29.aspx

By using a CMS we are using someone elses 'reusable code', by building on top of a framework, or even using someone's scripting language we are all running at some level of abstraction through reusable code. We are at the application level - few of us are creating languages but many of us are creating bespoke applications.

The languages and frameworks we use don't often provide application level functionality, instead they provide the bones with which we make the skeleton, and often they provide us with multiple options.

So we are at the next level, the applications themselves. Does this mean we don't create reusable code? that we sit atop the mount of others? Certainly not.. As a web agency we work with a variety of clients in a variety of industries but if we think about it these aren't too different.. We've got CRUD operations, entity/list manipulation, email, security, performance considerations.. all of which could be said to apply to almost any project and so should be kept separate.

Why?

So let's think about why we should be maintaining our own common codebase on top of all the other peoples code we are reusing... starting by breaking down a view of project code:

The onion of project codebases

Fig 1.0: The world of project code.

The above diagram indicates the categorisation of code I like to consider when developing a website/application. A codebase can be broken down relatively simply into:

  • Level 1: Code that plugs holes in the language or framework
  • Level 2: Code that could in theory be used by any website
  • Level 3: Code that is specific to a particular client, for example, they may have a bespoke system (human or technological) that you are integrating with that no other client will
  • Level 4: Code that is specific to the particular project or problem that you are working on

You could go even lower, although I won't for the purposes of this post, and say that beneath level 1 there are the design patterns and algorithms that you favour that reach further than even one language choice. Equally you could suggest that in parallel to this world is the breakdown of code in competing company codebases. But before someone mentions Schrodinger's cat lets get onto the benefits of keeping a common codebase. Starting with the most obvious and hyped...

Reuse

One of the most important things to note is that No project is bespoke. No project sits solely on that outer rim of the world even if it sits atop an off the shelf system at the lowest two levels. Often there is very little about a project, from a development point of view, that is actually bespoke. If your site is purely content you're talking about a CMS. If you are integrating with a third party app there's a degree of wrapper code that is distinct from the project specific application.

To take it further if you are manipulating data in some way, outputting reports in CSV, encrypting some data or interacting with a database this should be created free from the rest of the system and reusable.. to take it to the extreme, outside of UI wiring, some projects could be made up almost solely of calls into a common codebase.

Speed

If you are reusing code to that degree your development times will be that much quicker. Need to two way encrypt something? nip into your common encryption code and your done.

But let's think about this some more:

Thinking Further

Quality

If you are constantly reusing code you will also be constantly fixing it, refining it, testing it in different contexts and scenarios. You won't finish a project and not look at its codebase again until a year later when some obscure bug gets reported.

This has obvious ties to maintenance and upgrades. If you find a better or more secure way to do something it may be as easy as updating the common libary version used by projects. This is less possible if developers have rolled their own solution to all problems. 'Oh our encryption isn't very strong. I've updated my method, did you use similar?'... 'yes but I called it something else and it's mixed in with the integration code I did'... 'oh'

Knowledge sharing

If you're working within a team there's always the concern that you might be redoing the work or research that someone has already done. Short of asking around everytime you embark on the smallest of algorithms you can search the common codebase (perhaps paired with a team wiki) allowing others to get on with their work while you benefit from the shared knowledge base.

By this means you are capturing and sharing the knowledge of prior team members, contractors and others who are not in the office that day.

Process sharing

Short of coming up with a programming style guide (that you toil over for weeks until realising no-one will bother to read it) the common code library acts as a vehicle for convergence among the different programming styles of the team. As you each add and modify items within the common code you come to an understanding as to naming conventions, architecture and style purely by absorbing the pre-existing approach and fitting additions around it. What's more this isn't seen as a convention that is pushed upon the team nor is it autocratically defined by a single lead. It grows and evolves.

Expectation setting

If a new team member joins they could trawl through old projects to get a feel for approach or they could sit in a meeting or training day, or even be assigned a mentor. Ultimately though, providing them with a good chunk of reusable code is an easy expectation setter. It allows them to quickly see and guage the combined wisdom of the team, as well as acting as a base that they can expect to see in projects they are assigned to work on. Indeed, if they are particularly junior you can consider the common code base an effort in avoiding bugs as you are providing them with a big chunk of, in theory, bug-free code.

Furthermore it can provide a natural dividing line where code reviews can take place (at the gateway into the main common code branch). It can also be seen as a performance indicator. At the end of a project you could rightly expect to either find a lot of calls into the common code or a lot of new common code. If not, why not? Is the project really that bespoke? were there contributing factors (lack of design time, a short terminist perception of 'not enough time') that need to be addressed? Even better, have they found issues with the common code and applied fixes or updates?

Design enforcement

Ultimately by having a common codebase and by categorising the code you create into the four levels you are forced to ask questions of yourself as you code. 'Can i extract some of this?', 'Would this be beneficial to others?', 'How can I better abstract this?', 'Is this likely to be needed by all the clients apps or just this one?', 'Is this of good enough quality to sit aside the rest our common code?' and perhaps most importantly 'If it's not in our common codebase is it in someone elses?' Why am I not looking for and using that? (and if it's not out there you've just found a gap to fill and a question you can answer on stackoverflow).

What more can you do with it?

Outside of your own team/company if you've built a set of reusable components/classes/functions, and you've done this in a way that you can easily segment into the various levels, you could decide to put it out there, open source it as an addition to the public space for your stack of choice (with the bonus that at the first two levels you can be sure it's not even putting client confidentiality at risk).

How to do it?

  • Set aside a central area in source control (you're all using source control right?)
  • If you're creating it for the first time go back over some projects and extract as much as you can
    • Even if you don't refactor that project to use the common code just yet at least you've pulled the knowledge out of it for future use
  • Ensure the team are completely aware of its location and how it's to be used
  • Ensure there is a review process in place
    • Perform code review for additions and rolling reviews of the code in relation to changing standards/upcoming tech
  • Decide upon an organisation method
    • Within the .NET world I prefer to mirror the System namespace with my own company name. In this way any consumer already has a frame of reference for where they would expect to find something.
  • Keep it up to date
    • This may even include eventually delegating calls directly to the framework if they plug the holes you plugged some time ago

Downsides?

Of course as with anything there can be perceived downsides. Maybe there are battles against management, against short sightedness that you have to overcome. But this is where the senior devs have to take on the internal salesman role.

Pragmatism, though, must not be forgotten. Don't go around suddenly making every minor thing a common code class 'just in case you want to swap it out later'. Be realistic, keep in mind good programming practices... SOLID, DRY, KISS and YAGNI etc.

Conclusion

People talk of Utility Belts, and Reusable Code and fret over it a lot. Ultimately any good developer should already be thinking about reusability and more generally the idea of a common codebase. The key is to decide upon a good structure, a method of introducing it to the team and a plan for keeping it ticking over. As well as being aware of the less hyped benefits such as performance indicators, training tools, design enforcement and encouragement to reuse external code (and provide yours for reuse by others).

Embrace your common codebase. It's more than just some utility functions in an include file.

Appendix - So what's in mine?

Some examples of classes and namespaces that are in my common codebase...

  • BaseControllers
  • BaseRepositories
  • Extension Methods per primitive types
  • CacheManagers
  • GenericSerializers
  • Encryption
  • Image Manipulators
  • Mailers
  • Compressors
  • Validators

]]> Extending Xml: Two birds with one stone? http://cargowire.net/articles/extendingxml http://cargowire.net/articles/extendingxml Craig Mon, 05 Apr 2010 23:00:00 GMT Mini post introducing extending Xml with a few examples from cargowire.net I remember once sitting in a classroom being told Xml is great because you can make up your own elements. But I didn't quite get it... Who or what would care about my made up names?

Well it turns out it's all rather simple. To me it also has the side effect of tying in nicely to a well known programming principle:

DRY : Don't Repeat Yourself

(and don't repeat anyone else for that matter - use what's already there!)

When developing an XML/XSL driven site such as cargowire.net you will be representing your own data as XML. However the things you are trying to represent are rarely entirely unique. There may already be an XML format for the type of information you wish to portray, or one that exists for a similar purpose to yours but with some aspect added or missing from your needs.

So why not bend those to your will rather than starting from scratch, and then use the same XML for multiple purposes. Your 'engine' can then save on transforms and reuse XML generation code (which can also mean reusing a single cache or file).

First, some background

The tried and tested example of namespacing and extending XML is that of HTML and XSL. Below is a snippet of HTML from cargowire.net that represents part of the header of the site.

<html xmlns="http://www.w3.org/1999/xhtml"> ... <div id="header"> <h1 id="siteTitle"> <a accesskey="1" rel="home" title="Home" href="/"> <img width="334" height="110" alt="" src="/Content/images/cargowire.png" id="logo" /> <span>Cargowire</span> </a> </h1> </div> ... </html>

It is rather familiar HTML (or to be more specific, with it's well formed structure, XHTML). The all lower case angled bracket element layout is a form of XML, in this case, within the 'default namespace' of xhtml.

The xmlns attribute on the parent html element identifies all children elements as part of XHTML as specified by the w3c (with the known elements and attributes that that entails - as described at the namespace uri). If you followed the link on namespace defaulting above you'll know that namespaces can be mixed. And further, if you're a programmer this idea of namespacing to allow the use of different items with the same name will be very familiar to you.

To illustrate this, below is an excerpt from the cargowire.net XSL templates showing this kind of 'mixing':

<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="2.0" xmlns="http://www.w3.org/1999/xhtml" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:ms="urn:schemas-microsoft-com:xslt" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> ... <!-- Elements within anything but the default namespace are prefixed --> <xsl:template match="cargowire"> ... <div id="container"> <div id="content"> <h1 id="contentTitle"> <xsl:apply-templates select="page" mode="title"/> </h1> <xsl:apply-templates select="page" mode="content"/> </div> </div> </xsl:template> </xsl:stylesheet>

As you can see the XHTML namespace is specified as the default (line 3). Further namespaces are declared via multiple namespace attributes on the root stylesheet element (lines 4-7) with a colon separating 'xmlns' from the namespace prefix that will be used e.g. 'xmlns:xsl'.

In this way parsers can be sure of uniqueness when processing a particular xml document. In the XSL example above the processor identifies items with an xsl prefix as transform processing instructions whereas those with the default XHTML namespace are left to be written to the output directly.

This idea of mixing one set of known XML elements/attributes with another can be expanded to our own XML design. Here's a couple of examples from cargowire:

Scenario A: Sitemap

One of the obvious items of information required by a website is a menu structure. This could be represented in any number of ways. But before jumping in and creating a new nomenclature it's worth stopping to think what other purpose this xml could serve.

You will want to use your 'page structure' xml to present a menu to users but you may also want to present this information to other consumers. Sitemaps.org defines a standard for representing a website's sitemap that can be submitted to search engines. This can obviously also be used to represent your navigation. However in the case of cargowire I wanted to add a 'subtitle' to each menu item.

There was no scope for doing this within the sitemaps protocol, which left me with two options. One, that I create a bespoke xml schema for my sites purposes, with a transform to enable output in the known sitemap.xml format. The other is that I keep the sitemap.xml format and 'extend' it with my own elements/attributes.

Below is the 'extended' version:

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:cargowire-sitemap="http://cargowire.net/cargowire-sitemap" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd http://cargowire.net/cargowire-sitemap http://cargowire.net/cargowire-sitemap.xsd" > <url> <loc>http://cargowire.net/articles</loc> <lastmod>2009-08-29</lastmod> <changefreq>weekly</changefreq> <priority>0.5</priority> <!-- My added content --> <cargowire-sitemap:accesskey>2</cargowire-sitemap:accesskey> <cargowire-sitemap:pathandquery>/articles</cargowire-sitemap:pathandquery> <cargowire-sitemap:title>Articles</cargowire-sitemap:title> <cargowire-sitemap:subtitle>Things I think about</cargowire-sitemap:subtitle> </url> ... </urlset>

This can then be accessed in the XSL by referencing the namespace. Both in the root stylesheet element and then when matching the particular elements:

<xsl:stylesheet ... xmlns:s="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:cargowire-sitemap="http://cargowire.net/cargowire-sitemap"> <xsl:template match="s:urlset" mode="nav"> <dl id="pNav"> <xsl:apply-templates select="./s:url[cargowire-sitemap:pathandquery/@showinnav = 1]" mode="nav"/> </dl> </xsl:template>

This has saved on having an additional transform whilst allowing me to ensure that only parsers expecting/looking for the cargowire namespace are aware of it.

Scenario B: Feed Aggregation

TheBarn section of this site pulls in feed contents from a variety of sources (as discussed previously, using yahoo pipes). This content adheres to the RSS xml spec and contains all the information I need to display a listing except for one thing. On my barn page I also display a small avatar of the author.

Following the example above a gravatar element can be added to the 'item' element of the rss feed:

<item> ... <cargowire:avatar url="http://www.gravatar.com/avatar.php?gravatar_id=f953df82b2a3f65e0acb9b3897908be0&amp;rating=G&amp;size=40" /> </item>

Doing this with Yahoo Pipes

Unfortunately at time of creation I was unable to do this addition within the Yahoo pipes interface i.e. specify a namespace in the root element output to allow the avatar element within the items to persist (see some forum posts regarding it here). So currently I, as the consumer of pipes content, have to add any custom information I want at my end.

Defining your extensions

If you are using a tool like Visual Studio you may be able to validate and/or receive intellisense (autocomplete) on your XML if you specify an XSD. An XSD can also be used to validate an XML document ensuring that a document will not cause any suprises for any consuming code.

<xs:schema id="cargowire-sitemap" xmlns:tns="http://cargowire.net/cargowire-sitemap" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://cargowire.net/cargowire-sitemap" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="pathandquery"> <xs:complexType> <xs:simpleContent> <xs:extension base="xs:string"> <xs:attribute name="rel" type="xs:string" use="optional" /> <xs:attribute name="showinnav" type="xs:boolean" use="optional" /> <xs:attribute name="accesskey" type="xs:string" use="optional"/> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element> <xs:element name="title" type="xs:string" /> <xs:element name="subtitle" type="xs:string" /> </xs:schema>

A namespace uri will often lead to a page describing the namespace and include links to the schema definitions (see the XML Schema namespace uri itself for an example).

The schemaLocation attribute (as seen in the sitemaps.org example in fig 3.0) can be used to identify the XSD location for a particular namespace. The attribute value will be a list of key value pairs. The key being the namespace uri and the value being the schema location (use xsi:noNamespaceSchemaLocation for the default namespace).

Although XSD's are not the focus of this article it is worth knowing how to read these attributes when investigating XML schemas published by others.

Conclusion

Extending XML can be an extremely flexible way of addressing multiple problems within one Xml document. Doing so acts an extension of good programming practice - before starting, look to build on what already exists.

]]>
The Joel Test no.11 http://cargowire.net/articles/joeltest11 http://cargowire.net/articles/joeltest11 Craig Sun, 21 Feb 2010 16:00:00 GMT During the Boagworld 200 show Drew Mclellan, Rachel Andrew, Paul Stanton and I discussed the Joel Test. One of the tests we didn't get on to was test number 11... The application process is there for two reasons. One, for the employer to get to know if the employee is a good fit. And second for the employee to get to know if the employer is a good fit.

With any role a new hire needs to address a number of 'transferable skills' questions such as 'can this person communicate clearly' and 'can this person work with others'. However, on top of this each role has specific skillset requirements. It is these requirements that need bespoke methods of identification. The question is, what methods should we use?

The developer application process

Developer application processes can vary greatly. However their focus must be 'is this person able to program at the level we require?'.

Here's just a few examples of the methods I have encountered myself:

The "Old school" approach
  • Phone interview
  • A single, in person interview
The "Mini contractor" approach
  • Phone interview
  • 1 paid day on the job
The "Blue chip" approach
  • Structured Application Form instead of CV/Cover letter
  • Phone Interview business
  • Phone Interview technical
  • Recruitment day including Apptitude testing and monitored group activities
  • Second recruitment day including multiple interviews (sometimes videoed, sometimes requiring a pre-prepared presentation)
The "Do something right here, right now" approach
  • Phone interview
  • Business interview
  • Tech interview + coding on a whiteboard
The "Show us some code" approach
  • Phone interview
  • Minor coding project
  • In person interview

The Joel Test #11

In his article on interviewing for new developersJoel Spolsky identifies two key aspects to look for in new hires. That they are smart and that they can get things done.

The Joel test (a means of measuring the quality of a software team) provides a pretty compelling argument as to why candidates should write code as part of the application process.

  1. Do new candidates write code during their interview?

    Would you hire a magician without asking them to show you some magic tricks? Of course not...

    ...Yet, every day, programmers are hired on the basis of an impressive resumé or because the interviewer enjoyed chatting with them. Or they are asked trivia questions ("what's the difference between CreateDialog() and DialogBox()?") which could be answered by looking at the documentation. You don't care if they have memorized thousands of trivia about programming, you care if they are able to produce code. Or, even worse, they are asked "AHA!" questions: the kind of questions that seem easy when you know the answer, but if you don't know the answer, they are impossible.

    Please, just stop doing this. Do whatever you want during interviews, but make the candidate write some code.

Joel Spolsky - http://www.joelonsoftware.com/

The big question

So how do each of the approaches above answer the big question "Can this person actually develop software with us / the way we do / the way we intend to in the foreseeable future."

If we take a look back at some of the variants only a few actually ask for code:

Can you develop?
Old schoolA technical representative will quiz youAs part of an interview I was once asked "So are you comfortable writing Javascript functions?". I replied "Yes". Needless to say the only party that learnt something here was me. And I only learnt that the technical interviewer either wasn't very good at interviewing, or wasn't very good in general. The problem is, what can you ask verbally that actually proves competence?
Mini ContractorAt the end of the day the employer sees your code and assesses how much help you needed from othersIn this case the company needs some work for you to do that you can get up to speed with quickly (rather than wasting time teaching you) and is not under NDA. This approach can be useful to see how the applicant works in your environment but has extreme time costs for both parties, particularly as their presence may disrupt 'non-interviewing' members of staff.
Blue Chip (legendary logic tests)Answer a thought experiment/riddleI've not encountered this myself during interview - the concept is almost mythical. Although logic questions may, like apptitude tests, give an insight into how 'smart' someone is it is nowhere near as directly related to programming as getting actual code samples to be done/provided.
Right here right nowProduce a code sample to a particular problem in a short time frame while being monitoredRequires a relatively 'trivial' task that can be completed in a short amount of time. Being watched adds abnormal pressure but maintains control over the entire process and removes the ability to cheat the system. If the situation doesn't involve a computer (code on white board) it is quite different to the expected role.
Show us the codeProduce a code sample to a specific set task prior to coming in for interviewCan be 'gamed' (completed by someone else and/or with abnormal effort - 'yeh it only took 2 hours *cough*every minute since you gave me the task to now*cough*'). Doesn't give you a direct insight into the process only the process as viewed by the participant retrospectively.

If we agree that completing real code in some way is the only way to identify the programming ability of a prospective candidate we rule out all but the last two approaches (with 'right here right now' and the 'mini contractor' being roughly equivalent but for the probable time frame involved). And then it becomes a case of which is better?

What do we use?

At Headscape we use a process similar to 'Show us the code'. After a CV/Covering letter and phone interview sift we ask applicants to complete a mini project (based on a spec provided) and submit it to us as the next stage. This is for a number of reasons:

  • Asking programming questions verbally is inherently difficult. It can be tricky to avoid trivia style questions and is not particularly representative of day to day work.
  • Asking someone to code on a white board without the luxury of intellisense or google will filter out a chunk of applicants however it doesn't necessarily provide you with a full picture of them. Such testing relies on being able to generalise the success of creating a small algorithm to overall success on the job and doesn't account for 'off days'.
  • The actual output we receive is not so much 'marked' with a pass or fail (although it can be used to assess whether an applicant is at the level we require). The main benefit from our point of view is twofold... A useful effect of asking for new code is that the commitment required acts as a 'desire filter' on the applicants behalf. Applicants sending mailshot CV's to multiple jobs may be put off continuing down a path that requires more commitment from them - and this is a good thing. As an employer we want employees who really want to be with us rather than just someone who needs a job.
  • By asking them to complete new work in their own time we do not force them to have an extended stay at our offices for testing nor do we 'suprise' them with an algorithm question on the day. The other benefit therefore is that the technical part of the interview can revolve around the task. "How did you go about it?", "What did you find difficult?", "What did you need to research?", "What would you improve?", "How does this solution account for extensibility?", "Did you reuse some of your code/third parties?", "Did you satisfy the spec". All of these questions are only available if we have an extended code sample. And by setting each candidate the same mini-project it is more comparable than discussing their previous most recent project. It also gives the candidate scope to impress us by going the extra mile. For example I have previously been asked to write an IsPalindrome function on a white board. Comparing that to being given a mini project there is clearly more scope for me to show my desire (by adding extra functionality), show my planning skills (by building in extensibility), show my decision making (by using/not using third parties or previous code). All things that would be relevant to a developer role but are difficult to assess when reviewing single algorithms.

The argument is essentially the same as the coursework vs exams debate from education. Although coursework is more open to cheating and less able to be tightly controlled it is actually more like working life.

Discussing the project can easily identify if the candidate has had some 'assistance' from a third party. The main shortcoming then is not knowing exactly how much of the time between phone interview and in-person interview the candidate spent creating the output they provided. In my view this shortcoming is balanced by being able to have an in-depth discussion of the project. The speed of response and passion in their discussion surrounding this should provide pointers to how 'smart' they are.

Any suspicions or a large amount of applicants can be filtered by doing an initial technical interview over the phone regarding the project if necessary.

As an applicant

So thats all well and good as an employer. Just sit back and fire out homework for your applicants. But as an applicant is it merely another hoop to jump through?

When I've been an applicant myself I actually prefer to do code in some way. Not because I like to be tested or even just because I like to write code but because it allows me scope to get a feel for the employer.

  • Do I get a glazed look on the face of the technical interviewer when I discuss some aspect of the project?
  • Did they generally agree with my approach or are they entirely different?
  • Did they notice the bit I rushed?
  • Did they offer a different approach I hadn't considered? (can I learn from them?)
  • Did they smugly point out a minute flaw to establish their dominance
  • Did the back and forth about my code at times slip out of interview mode and become more like a discussion with colleagues?

All of these points allow me to guage my half of the application bargain "Is the employer a good fit for me?".

Reservations?

While agreeing with Joel that Smart does not mean 'knows the answer to trivia questions' I also understand that by asking for a mini-project to be completed we are asking for a reasonable amount of commitment from the applicant. However we both benefit from this in the richness of the interview process that follows.

Something we have also considered at Headscape is changing the 'test' to a situation where we provide a solution to the applicant and ask them to extend it in some way. This would be more realistic (most projects are continuations of old ones, or built on a base codebase rather than clean slates) and would also allow us to ask the applicant their thoughts on the project we provided. Would they have done it this way?

Allowing them to critique us not only assists their desire to judge if we are a good fit for them but allows us to see their analytical and critical skills.

In Closing

Our interviews involve key personal (representatives from each team PMs, Directors, Developers) and we must assess the standard job interview issues. However when it comes to development some form of coding is essential. In our case we favour the 'coursework' style. It may be that a mix of both is appropriate. With all things 'it depends'. If you expect 100 applicants to get to the testing phase then assessing those projects will be a huge undertaking. But relying on only a small in-person algorithm test can be difficult to generalise potential success from. Mixing the two, by bringing in a candidate and asking them to code all day may seem like an ideal compromise but requires a single fixed large timeframe commitment from both parties. We also all know how different it is to code with someone watching over your shoulder.

At all times we need to consider the benefit for both us as employers and applicants as potential employees through the process. We are not the only ones making a big decision. If we can somehow forge the process to allow the applicant to test us we will inevitably have a better new hire in the long run.

]]>
.NET Dev 101 (part 2) http://cargowire.net/articles/dotnetdev102 http://cargowire.net/articles/dotnetdev102 Craig Thu, 28 Jan 2010 23:00:00 GMT A follow-up to my .NET Dev 101 rant from early 2009. Aimed at beginner to intermediate .NET devs. Some time ago I blogged about a number of areas of the .NET Framework that people really should be both aware of and actively using. This was driven by working on existing codebases that appeared to show a lack of knowledge of some fundamental aspects of the framework and associated languages.

This time around the points aren't necessarily as small and 'obvious' as the items in the original list. However they are powerful aspects of C# or VB.NET that are useful to know as a beginner and can even seem to slip people by who have been working with .NET for some time.

1) Extension Methods

An early, obvious one, Extension methods have been available in the .NET framework for a while now. Essentially they can be used in place of a static method that performs some action on it's first parameter - using additional parameters if necessary.

After creation and referencing they manifest to the developer as instance methods on the type being 'extended' with full intellisense support (this syntactic sugar is actually just the same as a static call behind the scenes).

An Extension Method Example

public static class StringExtensions { // Notice the 'this' keyword before the first parameter to signify that this // is an extension method for string public static int ToInt(this string @string, int defaultValue) { int value; return int.TryParse(@string, out value) ? value : defaultValue; } public static int? ToNullableInt(this string @string, int? defaultValue) { int value; return int.TryParse(@string, out value) ? value : defaultValue; } } // Call style string a = "5"; int? b = a.ToNullableInt(null); // 'this' parameter is omitted

There has been a lot of discussion surrounding the acceptable usage of extension methods (which many people regard as a code smell outside of linq). However, outside of fluent interfaces, they can be extremely useful at simply removing repetition. In the example above we can see how the minor process of parsing a string into an integer can be extracted away from wherever it is needed in the codebase into an extension method for string. This then allows the logic of an application to be more concise as the non-business logic related/mundane tasks are hidden away.

The key difference for me, with these small applications of extension methods, is that they are not used in areas where the functionality could possibly be swapped out in the future. In these cases a more Object Oriented Polymorphic approach would be favoured.

2) Build with the framework in mind

Some time ago, when I wrote about Date Formatting in XML/XSLT I made reference to the following sanity check before embarking on any coding endeavour:

Does this new piece of functionality fit within the framework somewhere already?

The reasoning behind this is both an issue of maintenance and expectation. If a project closely works alongside the extensibility points of the framework new developers can have an expectation that logic is implemented in a way that fits with their pre-existing knowledge. This includes general library design as well as how new functionality is created.

A specific example

string.Format(new BritishDateTimeFormatter(), "{0:ddx}", dt);

The British date formatting example shows an implementation of an IFormatProvider, ICustomFormatter to add british suffix ('th', 'st', 'rd') formatting to dates using the 'x' character. The issue here is that any object could have been custom made to provide methods for british date formatting. However by implementing a pre-existing interface (IFormatProvider) the code can be used with the string.format method and can be reused by any other library that has decided to use the 'built in' IFormatProvider.

Many similar interfaces exist (IConvertible, IComparable, IFormattable, IEquatable etc) as well as the provider model for things like membership etc. The point is to look for these 'fits' within the framework before just starting from scratch.

3) Custom operators

To continue the idea of building to the framework rather than just with it lets take a look at a quick example of overloading operators. The general pattern is that you implement a static method within a Type definition that uses the 'operator' keyword and symbol/TypeName to identify itself as an implementation of an operator.

This allows the specification of what happens when you do MyCustomTypeInstance + MyCustomTypeInstance or (MyCustomTypeInstance)myStringValue. Available operators include ++, --, !, +, -, *, /, %, ==, !=, >, <, &, |, ^, <<, >>, >=, and <= as well as conversions between types.

Examples

One of the canonical example's of this for me is the 'Cycle' example as discussed by some of the Microsoft Literature whereby the + operator is overloaded for a custom Cycle type. This allows the Cycle to control addition to an inner integer value and cycle back to the beginning of a range when it is added to e.g. a Cycle is created with min 1 and max 5. When 1 is added to a cycle with value 5 the value becomes 1 instead of 6.

Another example below shows how custom conversion can also be implemented as operators on a class:

public MyClass { ... public static implicit operator int(MyClass arg) { return arg.Id; } } // Calling example MyClass myClassInstance = new myClassInstance(5); int i = myClassInstance;

In this case an integer can be set directly from the custom instance (which could be a value that is calculated or even private and not exposed in any other way).

This kinda of approach can be very powerful. However the decision to use them should take into account the slightly hidden nature of them. For example you could override the cast to boolean operator to do validation, but doing so strips you of the ability to expose a clearly named 'Validate' method (or you end up doing both leading to inconsistent usage of the two in consuming libraries).

4) IHttpModule

As developers of .NET web applications we often find ourselves using the Global.asax file to specify actions to undertake on particular events. The only issue here is that to reuse this functionality you need to merge pre-existing global.asax files between projects. Additionally they are not particularly well defined. That is to say, that you can't look at the name of it and get a feel for what it does. However, if we use implementations of IHttpModule instead, they can be encapsulated. For example you might have an AuthenticationModule or an ErrorModule as below:

Example - Error Handling

public class ErrorModule : IHttpModule { ... public void Init(HttpApplication application) { application.Error += new EventHandler(Application_Error); } public void Application_Error(object sender, EventArgs e) { ... logger.LogError(string.format("Unhandled exception: {0}", exception)); } } <!-- Web.config extract --> <system.webServer> <add name="ErrorModule" type="Cargowire.Common.Web.ErrorModule, Cargowire.Common.Web" /> </modules>

As you can see the Application_Error event usually found in global.asax is part of the IHttpModule specification allowing multiple different event handlers to listen for the same events rather than clogging the global.asax with disperate concerns.

5) IHttpHandler

When a url is requested the code that handles generating a response is an HttpHandler (System.Web.StaticFileHandler, System.Web.Mvc.MvcHandler etc). Custom handlers can also be created, implementing IHttpHandler and registered in the web.config they can respond to requests to a specified path. They are particularly useful when no real response is required or if the response is plain text, with that added benefit that they incur far less setup (in terms of wiring of post back, session etc that happens on normal page loads).

Example - Session Heartbeat

A common problem encountered in systems with prolonged data entry is the possibility that the session times out between edits. To keep a session alive some simple javascript can be written to poll the server to keep alive the user session. There is no real response needed and definitely no need for a full page request process to begin...

/// The IRequiresSessionState does nothing but mark this handler as requiring the Session /// context to be available to the handler. This can be omitted if session is not required public class Heartbeat : IHttpHandler, IRequiresSessionState { public readonly bool IsReusable() { get { return false; } } public void ProcessRequest(HttpContext context) context.Response.ContentType = "text/plain" context.Session("keepalive") = DateTime.Now.Ticks context.Response.Write(context.Session("keepalive")) } }

The above can be implemented as a code file and then registered in the web.config or as a .ashx file in your web project.

Another recent example where using an IHttpHandler can make sense is as a responder to an AJAX auto-complete script. There is no need for session, no full page output, no separate use case, the functionality only exists for javascript to call it and receive a json object containing suggestions for the input field. So there is no need to implement this as a complete page or controller/view - Instead just a light weight handler.

Before you leave

It's important to note these lists aren't meant as a teaching aide for learning .NET from scratch nor does usage of any of the above immediately make you a better programmer. Extensive knowledge of a language and framework is beneficial but not without a grounding in how to utilise it effectively and in a considerate manner as regards maintainability, reuse and handover to new devs.

Hopefully this list has highlighted some areas for further reading. More info can be found through a plethora of resources including those mentionned in my 'useful for a .NET dev' post.

]]>
XSL for Designers? http://cargowire.net/articles/xslfordesigners http://cargowire.net/articles/xslfordesigners Craig Wed, 20 Jan 2010 23:30:00 GMT An intro to XSL using CSS as a basis for comparison. Applicable to designers and developers alike. At Headscape we use our own in house CMS. This technology is based on XML and XSLT with the XSL layer usually under the purview of the development team...

There is however, no reason why a proficient CSS user can't take advantage of, and work with XSLT. In fact, if the XSL is written in a more declarative, rather than procedural manner it can be very similar to working with CSS to style HTML.

Why Xsl?

XSL is a stylesheet language that can be used to 'transform' (the 'T' in XSLT) XML into some other output. I can go from:

<item> <name nick="Craig">Craig Rowe</name> <company>Headscape</company> <group>colleague</group> </item>

to:

<h3>Contacts</h3> <p class="colleague"> <strong>Craig Rowe</strong> (Craig) from Headscape </p>

Although the transformation is from one text ouput to another we can see the similarities to applying CSS to HTML. With CSS the HTML starts off in one form, default browser styling renders it in a particular way (with fonts, padding, positioning), user CSS is then applied turning it into a slightly different visual output (different fonts, padding, positioning etc). In the XSL example above the only difference is that the final outcome is another type of text output rather than a graphical display.

In terms of the process we can imagine:

Backend Coder → generates → XML → transformed by → XSL → into → XHTML → styled by → CSS → ending in a → Beautifully designed website

The neat separation between content and presentation is immediately clear. If the 'engine' of an application created, used and output XML, then XSLT could be used to create any output without the need to modify a line of code. In fact this is how cargowire is created (as I've pointed to briefly before here and here). Multiple outputs are provided purely by leveraging XML and XSLT.

XSL, as a templating engine, is also backend language agnostic. That is to say I could go from running my site on .NET to running my site on PHP or Ruby but maintain the same XSL as long as I could generate the same semantic XML.

There are other benefits too... Many web APIs provide XML or RSS based outputs. Both of which can be transformed into HTML using XSL.

And it's not just us that use XSL. For example, Symphony CMS is a PHP based CMS solution that leverages XSL as its templating engine.

Similarities to CSS

Both CSS and XSL are tasked with selecting particular elements within a document and applying some kind of property or change to them. Let's compare the differing selection syntax. The following are equivalent:

CSS SelectorsXSL Selectors (known as 'XPath')Plain English
1div#content p.intro//div[@id='content']//p[@class='intro']p with class 'intro' inside div with id 'content'
2#container thead th//*[@id='container']//thead//thth inside thead inside any element with id 'container'
3#content h3//*[@id='content']//h3h3 inside any element with id 'content'
4#content > h3//*[@id='content']/h3h3 as direct child of element with id 'content'
5#content, .content//*[@id='content'] | //*[@class='content']Any element with id 'content' or class 'content'
6ul.inline li:last-child//ul[@class='inline']/li[position()=last()]]The last li inside a ul with class 'inline'
7//a/@hrefSelect the href attribute of all anchor elements
8.The current context node

Some of the syntax will be familiar to experienced CSS users. For example a[rel=external] is a CSS rule that is almost identical in XPath //a[@rel='external']. The key differences to be aware of are as follows:

  • There is no shorthand for the id or class of an element in xsl, they are merely attributes that need to be specified in square brackets.
  • The separator between sections of a css rule is usually a space or class/id shorthand. In XPath it is a / (direct child) or double // (any descendant)
  • The element type is required (note the use of * in rules 2-5 instead of merely starting with [@id=content])
  • The / or // separators are also required at the beginning of an XPath statement unless the statement is intended to start from the current context
  • Comma separating CSS selectors essentially means 'this or that'. With XPath this is represented by the pipe character | (rule 5).

If you want to test out these XPath selectors try the Firefox XPather plugin which allows you to type XPath selectors in a console window and see what results are returned from your html.

The XPather plugin window

An XSL Stylesheet

The template below could be used to transform the example data above. Do not be put off, it is very HTML esque with some opening tags at the top and a few document type declarations like xml version and output method, with the real meat in the centre.

<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes" omit-xml-declaration="yes" /> <xsl:template match="/"><!-- Will match the root of the document and therefore run first --> <xsl:call-template name="contacts" /><!-- Calls a template to run by name --> </xsl:template> <!-- A named template --> <xsl:template name="contacts"> <h3>Contacts</h3> <xsl:apply-templates select="//item" /><!-- Apply all rules/templates that match the selector --> </xsl:template> <!-- A match/rule based template --> <xsl:template match="//item"> <p><!-- Attributes can be added as below or using curly brace shorthand e.g. class="{group}" --> <xsl:attribute name="class"> <xsl:value-of select="group"/> </xsl:attribute> <strong> <xsl:value-of select="name"/> </strong> <xsl:text> (</xsl:text> <xsl:value-of select="name/@nick"/> <xsl:text>) from </xsl:text><xsl:value-of select="company"/> </p> </xsl:template> </xsl:stylesheet>

Like HTML, XSL files start and end with an angled bracket element (<xsl:stylesheet>) and can contain any number of templates, which themselves will contain any number of statements including plain text output. Any <xsl:...> tags are part of the stylesheet and not output. Any other elements, such as the H3 seen above, will be output as is.

How it works

When this template is applied to XML the following will happen:

  1. A template that matches the root element is looked for and run
  2. The root template has only one instruction, to call the 'contacts' template
  3. The contacts template will start by outputing an H3 for the 'Contacts' header
  4. The contacts template then tells the XSL processor to apply any templates that match the specified selector. In this case 'any element named item'
  5. The template that matches this selector is called for each 'item' element in the xml (in this case there is only one)
  6. Inside the item template (where the current context is the item node itself - so the selectors do not start with a slash)
    • The p element is output with an attribute named class set to the value of the 'group' node
    • A 'strong' element is output with the contents of the 'name' node inside it.
    • This is followed by the plain text backet before outputting the value of the name elements nick attribute, some more text and finally the company node contents.

As mentioned earlier and discussed in the notes below XSL stylesheets can have a distinctly procedural feel to them or a more declarative. In the template above we get a flavour of both. The more procedural style occurs where a template is called by name (line 6) - akin to a javascript method being called that document.write()'s. The more declarative style can be seen where templates are set up to 'match' a selector statement (line 13 and 18) with apply-templates being called to tell the xsl processor to match those rules.

How can I try it myself?

As a developer I mainly use XSLT from within a backend language (in my case, .NET which supports XSL 1.0) however many browsers are also XML/XSL aware so it is quite easy to test locally without any backend code knowledge simply by adding the reference to the stylesheet in the xml itself.

<?xml-stylesheet type="text/xsl" href="items.xsl"?>

For an example of this please see items.xml and items.xsl (using view source to see the xml and xslt that is used). If you are using an XSL aware browser when you hit items.xml you should see the transformed html (which can be seen in firebug - view source will show the raw xml).

Using this technique the template generation can be done locally with example XML data before the intended application is even written. This can be used in conjunction with XPather for debugging.

Example from Cargowire

A more elaborate example can be garned from Cargowire itself. Last week I wrote about how Yahoo Pipes can be used to create an aggregate and filtered RSS feed. The output was a feed for the Headscape bloggers. On it's own this is useful for subscriptions however with XSLT we are able to present the content in an entirely different way.

The data source is standard RSS which we know is XML and can be transformed as such. A trimmed down version of the XSL for the barn page can be seen below. This transform occurs on the server side after code has retrieved the feed from Yahoo and before it sends a response to the user.

<xsl:template match="//page/*/*/channel"> <!-- Assumes a root matching template somewhere else in the XSL as well as the definition of the gravatar template and $formatstring variable --> <p>This is simply a combined feed from <a href="http://www.boagworld.com" title="boagworld.com">Paul</a>, <a href="http://www.edmerritt.com" title="edmerritt.com">Ed</a>, <a href="http://www.davemcdermid.co.uk" title="davemcdermid.co.uk">Dave</a>, <a href="http://www.robborley.com" title="robborley.com">Rob</a> and <a href="/about#stalk">Myself</a></p> <div id="publicationLinks"> <dl id="publication"> <xsl:for-each select="item"> <dt> <h3> <xsl:choose> <xsl:when test="string-length(link) > 0"> <a href="{link}"> <!-- if this is an external link mark it as so --> <xsl:if test="not(starts-with(link, 'http://cargowire'))"> <xsl:attribute name="rel">external</xsl:attribute> </xsl:if> <xsl:value-of select="title" /> </a> </xsl:when> <xsl:otherwise> <xsl:value-of select="title" /> </xsl:otherwise> </xsl:choose> <!-- A call to a template to output the avatar image --> <xsl:call-template name="Gravatar"/> </h3> </dt> <dd> <!-- call into some code to format the date after creating a variable --> <xsl:variable name="datetimestampformat"> <xsl:text>yyyy-MM-ddTHH:mm:ss+00:00</xsl:text> </xsl:variable> <!-- use curly brace shorthand to use xsl/xpath to set an attribute value --> <p class="published" title="{date:FormatDate(string(pubDate), $datetimestampformat)}"> <xsl:value-of select="date:FormatDate(string(pubDate),$formatString)" /> </p> <p class="abstract"> <!-- Disable output escaping will maintain html tags in the output --> <xsl:value-of select="description" disable-output-escaping="yes" /> </p> <xsl:if test="string-length(link) > 0"> <a href="{link}" class="moreLink"> <xsl:if test="not(starts-with(link, 'http://cargowire'))"> <xsl:attribute name="rel">external</xsl:attribute> </xsl:if> <xsl:text>Read More...</xsl:text> </a> </xsl:if> </dd> </xsl:for-each> </dl> </div> </xsl:template>

In the above stylesheet snippet we can see a template that matches the RSS channel element then loops through the items to produce an HTML based listing of the feed contents. Relatively self-describing constructs such as 'choose' and 'if' are used and so too are a couple of extras such as the call out to an external code object to format dates on line 33 and the use of not() and starts-with() on line 42. A variable is also defined on line 29 before being used on line 33.

If you want to find out more a good quick reference/start point for xslt 1.0 xpath and functions is provided by Mulberry Technologies.

Final Points

This article aimed to give you a taste of XSL and how it is used. As such we have kept to quite minimal templates and selectors however these core aspects of XSL should allow you to view and make ammendments to XSL templates without too much trouble. By using tools such as XPather and XSL in the browser you should be well equipped to make changes to and understand many XSL templates created by backend developers. It's also important to remember that although this example has discussed tranforming to HTML the output from XSL could just have equally been json, rss or even plain text.

The final example from Cargowire aims to illustrate a practical example and as such contains some more complicated functionality that is not fully described in this article. However if you are comfortable with HTML, CSS and perhaps a little javascript it should be relatively easy to follow.

Let me know your thoughts


Appendix A: Current Context in XSL

In XPath there are three main ways to start a selector:

  • /elementName - Finds the root element named elementName (in html only /html would match)
  • //elementName - Finds any instance of elementName in the entire XML document
  • elementName - Finds any instance of elementName as a direct child of the current context

In terms of the 'current context': If I was inside a template that had just matched 'item' an XPath of 'seconditem' would look for a direct child of the 'item' element that is named 'seconditem'. It would not match all 'seconditem' instances in the entire xml document.

In terms of CSS this could be seen as a rule that only applies to elements inside another rule. Or in jQuery a selector that runs from the 'this' context e.g jQuery('seconditem', this).

back - back to top

Appendix B: Declarative Vs Procedural XSL Stylesheets

It is my experience that many backend developers who move in to using XSL are keen to maintain the traditional coding paradigm of one thing following another until completion. Taking this view with XSL can lead to single large primary templates with many conditionals, loops and calling of sub templates.

This can make XSL difficult to read, particularly to non-technical users. However XSL is in its element when used declaratively. Instead of attempting to run down the XML as if parsing it in code simply define a number of rules that match the relevant parts and then apply those rules to the XML document (like CSS).

Lets look at a simple example comparison between two templates that do the same thing:

<addressbook> <name>Work</name> <items> <item> <name nick="Craig">Craig Rowe</name> <company>Headscape</company> </item> <item> <name nick="Craig">Craig Rowe</name> <company>Headscape</company> </item> </items> </addressbook>
Procedural StyleDeclarative Style
<xsl:templates match="/"> <h2><xsl:value-of select="name"/></h2> <xsl:for-each select="items/item"> <h3><xsl:value-of select="@nick" /></h3> </xsl:for-each> </xsl:template>

This style has the look of javascript structure where loops and tests occur in sequence

<xsl:templates match="/"> <xsl:apply-templates select="items/name" /> <xsl:apply-templates select="items/item" /> </xsl:template> <xsl:templates match="name"> <h2><xsl:value-of select="."/></h2> </xsl:templates> <xsl:template match="item"> <h3><xsl:value-of select="@nick" /></h3> </xsl:template>

This style has the look of a CSS structure i.e. a list of rules that match selectors

back to top]]>
Paginate and filter with Yahoo Pipes http://cargowire.net/articles/playwithpipes http://cargowire.net/articles/playwithpipes Craig Mon, 11 Jan 2010 23:50:00 GMT An intro to how Yahoo pipes can be utilised to paginate, and filter multiple datasources into one feed. Useful to delegate the hard work, leaving your code to handle just the desired content. Rapid decentralisation of our personal content has led many of us to have rather minimal websites with the main content hosted on any number of a variety of web services. The homepage then acts as a hub, virtual business card or placeholder instead.

The half way house

The middle ground then, between the more 'old school' all-in-one personal site and the business card style, are hybrid sites where, although the content may be hosted externally, it is still pulled in to the hub for central display and branding. This is probably the first contact many of us developers/designers have with a new API - trying to access it and pull content in to our personal locations. It can be seen in the large amount of twitter/brightkite/google maps 'badges' across our personal websites.

Indeed, on cargowire itself these three api's are used on top of connections to delicious (currently deactivated) and to a variety of RSS feeds for the headscape barn article listings.

Yahoo YQL and Pipes

The approach to site development described above can mean a large amount of research and development work for each new 'type' of thing you want to bring in to your site. YQL is Yahoo's attempt at helping standardize this for us (something that you will often find Christian Heilmann, one of Yahoo's Developer Evangelists, talking about). However the focus of this article is on another of Yahoo's offerings - Yahoo Pipes.

Pipes has been around for a while now (since back in 2007) and provides a nice GUI interface for accessing and manipulating the kind of data you can use YQL to retrieve. After signing up you will be able to create, manage and publish your pipes. Taking advantage of the documentation and examples provided.

The brief

Flexible pulling in of external feed content - appropriately filtered and limited.

Consider the following example scenarios:

  • You are sending requests for external content for inclusion on your webpage. Either:
    • Clientside javascript sends an ajax request for content
    • The server itself is requesting and merging the response with other content before sending down to the client
  • You are creating an iPhone application that intends to display custom or aggregated feed contents.

Without direct control over the feed it can be difficult to retrieve exactly what you need. This can then become an issue for the speed of your application. If I'm on my phone and I want to see the most recent items on a feed I don't want to have to download all 500 archive items before being presented with the top ten.

A simple aggregated Pipe

Below is a screenshot of the yahoo pipes editor. Using drag and drop alone you can select a number of modules from the left toolbar and position them on the canvas area as if sketching a flow chart. Dragging from the connector points allows the flow to be guided through to the pipe output.

Screenshot of the Pipes editor showing Cargowire and Boagworld feeds merged together

To create an aggregated pipe we use 3 types of module (in addition to the default 'pipe ouput' that comes with a new pipe). 'Fetch Feed' modules are used with an accompanying URL to specify the feed content that you wish to pull in. The 'Union' module under 'Operators' is then used to merge the two feeds together. These all then feed into a simple 'Sort' module which allows you to specify a particular field to sort by (multiple sort fields can be specified by using the 'add (+)' button on this module).

Filtering

So now I have a combined feed of Cargowire and Boagworld. However the Boagworld feed exposed from boagworld.com includes the podcast as well as blog posts...

Screenshot of the Pipes editor showing Boagworld feed filtered to exlude the podcast

To remove the items that I do not want I can use a 'Filter' module. This type of module can act either as a whitelist or a blacklist by blocking or permitting based on a list of rules. Rules can use the following operators: contains, does not contain, Matches Regex, is greater than, is, is less than, is after, is before. In the example above the items from the boagworld feed are blocked if the link contains the phrase '/podcast/'.

Paginating

With the feeds combined and appropriately filtered my only concern now, in consuming code, is to avoid large datasets when all I want to do is peek at the top 10.

To do this, and to allow my consuming code to control pagination itself, I need to be able to send parameters with my request for the pipe. This can be done using the 'user inputs' modules (which could equally have been used with the 'filter' module above to provide dynamic filtering).

The screenshot below shows the flow of the pipe with this implemented. The following new modules are used:

  • Split - will provide two connector points from one
  • Count - will count the input items and output a number
  • Simple Math - can be used for simple arithmetic
  • Number Input - can be used to pull a number from the request querystring
  • Tail - takes a number and feed input and returns the items after the specified number position
  • Truncate - takes a number and feed input and returns the items up to the specified number position
Screenshot of the Pipes editor showing Boagworld feed selecting 1st-10th item

Explanation

  1. The feed (or feeds) are fetched and pushed in to a split
    • The split is necessary so that the feed contents can be used later as an output but also as the source for calculations
  2. A count is performed to identify the total number of items in the list
  3. A 'Tail' is used to select the count minus a user input 'from' parameter. This small calculation is performed through the 'Simple Math' module.
    • i.e. to select from the 5th item out of 20 I need to 'Tail' the list by 'count' minus 'from' (20-5) or 15
  4. A 'Truncate' is then used to select the amount up to the 'limit' parameter
    • Combining a tail and truncate allows the specification of a start position and an amount of items to retrieve. e.g. to retrieve the items from 5 to 15 in a list of 20 the user will specify '5' and '10'. The 5 will be calculated against the count and use 'Tail' to retrieve the last 15 items. The truncate will then select the first 10 to result in 5-15.

Using the pipe

By setting a friendly profile and pipe url the paginated feed can then be accessed by any client using:

http://pipes.yahoo.com/cargowire/paginatedboagworld?_render=rss&from=2&limit=5

They can then adjust the viewing parameters as necessary.

By combining all of the above techniques we can use pipes to provide us with an aggregated Headscape Barn feed that is filtered to exclude podcast entries, sorted and then paginated based on user input.

http://pipes.yahoo.com/cargowire/paginatedbarn?_render=rss&from=2&limit=20

Final Thoughts

In this example I have fetched rss feeds, however Yahoo Pipes is also capable of sourcing data from a variety of input sources such as flickr, CSV and plain xml/json. For example I could use a 'Fetch Data' module to pull the same content from my site but using my .xml output instead of .rss. I can then use the 'Rename' module to provide an appropriate output. Equally I could pull content from an API that exposed json through GET requests (such as the twitter public API) and then layer on my own manipulation. Allowing me to implement a large chunk of functionality easily and quickly, delegating all the manipulation code to a third party.

This is exactly the approach taken with the barn feed on this site. The content is pulled from yahoo pipes leaving me only to concern myself with local caching and transforming.

In the case of Cargowire this request is done on the server side with the resulting XML transformed using XSLT into XHTML to send down to the browser. However I could also use the same pipe in JSON format for clientside development or as a simple embed html/script badge (as provided by Yahoo).

]]>
What's useful for a .NET Dev? http://cargowire.net/articles/usefulfordotnetdev http://cargowire.net/articles/usefulfordotnetdev Craig Mon, 04 Jan 2010 22:00:00 GMT Towards the end of last year I had some correspondance with a Boagworld listener who was interested to know what kind of resources I used for both dev and just plain keeping up to date... here it is in lovely blog post stylé. Day to day there are many resources and tools that are invaluable to me as a .NET developer. The following article discusses some of the most useful examples.

Preamble

Without sounding too grandiose about it, the Internet has brought so much information to our fingertips and as web designers/developers we are even luckier. The resource we add to each time we complete a project is also the resource we use to increase our knowledge and complete our work. I certainly do not envy software developers plying their trade before the Internet. The advantage of being able to run off and, in a split second, consult hundreds of thousands of other people's knowledge and expertise is immeasurable.

Not to get off point too much, but sometimes it's useful to remind ourselves how lucky we really are with the abundance of podcasts, blogs, websites and ebooks available to us. This is also why we should do our best to give something back, either via blogging ourselves or contributing to an open source project.

Personally

I find that the most regularly used resources, for me, are podcasts. As a commuter the ease of use and ability to add value to an otherwise unused 1.5hr travel time every day is too good an opportunity to miss. Secondary to that are blog posts. Most often accessed through some level of aggregration, whether that be through following respected professionals on twitter/huffduffer or subscribing to aggregated feed services, it saves time on that first sift. The third level then is 'feature length' content such as physical and electronic books. These are often most useful if you want to focus on something particular or train as a beginner in a new area.

Podcasts

Generally the podcasts that stay with me are those with a more discussive tone to them. They tend to hold attention better than more structured presentational style recordings (think Tutorial vs Lecture):

  • StackOverflow podcast

    An excellent replacement for a radio breakfast show. Joel and Jeff discuss a range of topics rooted in their StackOverflow trilogy (which also happens to be one of the highest profile ASP.NET MVC implementations right now).

  • Hanselminutes

    Microsoft Principal Program Manager Scott Hanselman's weekly 'talk show' podcast offers up some real gems as guests. With a knowledgable host able to navigate the useful topics well. Scott is also very good at ensuring any jargon or acronyms are explained (even if only briefly) to ensure you aren't left wondering what something means as it's discussed.

  • .NET Rocks

    A podcast that I have only dipped in and out of occassionally but that can also throw up some excellent guest content.

  • Boagworld

    Although not strongly development focused the Boagworld podcast is the first podcast that kept me hooked to my subscription. Its broad subject range is also particularly useful to maintain knowledge of the wider web community rather than getting too isolated in a backend developer world.

Websites / Blogs

  • StackOverflow

    Most google searches for a .NET based problem seem to throw up a stackoverflow entry at position 1 or 2 (and that's a good thing). An excellent community driven site, with a clean interface and vast catalog of knowledge. The old school forum paradigm is shaken up with a Q&A wiki based approach. Sign up and start collecting your reputation and badges.

  • Codebetter

    Some excellent blog content from contributors such as Jeremy D Miller (StructureMap) and Karl Seguin (Codebetter.Canvas).

  • DotNetKicks

    A favourite among many .NET dev's DotNetKicks does an excellent job of aggregating .NET related links and resources.

Misc / Books

  • A Foundations of Programming eBook by Karl Seguin

    An eBook that I really enjoyed reading and would recommend to any .NET developer - and it's entirely free!

  • Microsoft Qualification Books

    Many employers put effort into becoming Microsoft partners and pushing their staff through Microsoft Certification. Regardless of the pros and cons of this the books put out for the qualification programs can act as excellent references, especially early on.

Events

On top of daily blogs/podcasts/books I'd recommend attending as many events as possible, many are free (although will involve your own time) and others are reasonably priced if you have scope within your organisation for training costs.

  • DDD Developer Days

    A free to attend event that often has a great line up of speakers and .NET folk to meet (I've seen the likes of Scott Guthrie and Jon Skeet speaking at these events).

  • Web Developer Day

    Another free to attend event hosted at Microsofts Reading campus - very similar to DDD but with a specific web focus.

There are also many localised user groups and events (barcamps, geekups etc).

I try to ensure I write up notes on the events I attend. Even if time is tight a quick post with a sentence per attended talk is helpful to think over some of the information you absorbed throughout the day.

Tools

  • SQL Compare/SQL Data Compare

    RedGate offer some excellent dev tools. Of particular note are SQL Compare and Data Compare which allow you to perform Diff's on both your DB structure and data.

  • Reflector

    Now also owned by RedGate, Reflector allows you to browse any dll's contents including those of .NET itself. Very handy if you're trying to figure out why something acts a particular way in the framework (or in worst case scenarios trying to recreate your source from published copies!).

  • Phil Haacks ASP.net routing debugger

    When ASP.NET MVC applications get big routing can become complicated. This is where Phil Haacks small library comes in, allowing you to see a breakdown of which routes match in a tabular format simply by adding a reference and a single line of code.

  • StructureMap

    The IoC I'm currently using on for Cargowire. Very flexible and powerful.

  • MVCContrib

    A useful library of additions and extensions for ASP.NET MVC including controller factories, model binders and view engines.

  • LINQPad

    A particularly useful tool allowing you to try out and run linq queries against a data source.

In addition I hear extremely good things about resharper but have never stumped up the cash for it. Regex Buddy is another that can be particularly useful.

Hammering it home

This post is intentionally link heavy to try and point to as many resources as possible. I encourage everyone to Blog about your experiences, create test applications, solve random short problems, play around in your own codebases... but do something, and do it regularly to help nail down concepts and to experiment with new things.


N.B: My apologies but commenting is currently not live on cargowire. Please feel free to feedback through other means before commenting goes live.

]]>
Cargowire MVC: Routing http://cargowire.net/articles/cargowiremvcrouting http://cargowire.net/articles/cargowiremvcrouting Craig Sun, 06 Dec 2009 22:00:00 GMT Cargowire is now running .NET MVC. This is the first in an intended series of articles discussing the implementation and changeover from .NET WebForms... starting with Routing and URL design. Cargowire is now fully .NET MVC. Although it looks the same, I've been able to take advantage of the new (ish) MS implementation of the well known MVC pattern and surrounding technologies. During the changeover I wanted to be sure that my urls remained the same.

URL Design

When I first created cargowire I wanted to ensure my urls were 'nice'. That is to say they stayed around, they were short, they were obvious and they were extensionless urls.

Cargowire itself is a relatively short domain name and my main site sections were as follows:

  1. /blog
    1. /blog/2
    2. /blog/dotnetdev101
  2. /articles
    1. /articles/2
    2. /articles/dateformattinginxml
  3. /about
  4. /notes

This was originally implemented using a third party library (Intelligencia.UrlRewriter) running as an HttpModule. Intelligencia used a rather traditional set of regex based rules in an XML configuration file (in this case, web.config). So for example the following <rewrite url="~/blog/([0-9]+)" to="~/default.aspx?p=$1" processing="stop" /> would match the pagination urls for the blog i.e. /blog/2, /blog/3 and rewrite that to /default.aspx?p=2, /default.aspx?p=3.

This method was pretty standard, among other third party approaches like the ISAPI Filter 'ISAPI Rewrite'. However .NET 3.5 SP1 contains the System.Web.Routing.UrlRoutingModule. With this library we are able to create routes in the following way and add them to a RouteTable:

protected void Application_Start() { // Via RouteCollection.Add RouteTable.Routes.Add(new Route { Url = "{controller}/{action}/{id}", Defaults = new { action = "Index", id = (string)null }, RouteHandler = typeof(MvcRouteHandler) }); // Or via RouteCollection.MapRoute RouteTable.Routes.MapRoute("DefaultRoute", "{controller}/{action}/{id}", new { action = "Index", id = (string)null }, null); }

This RouteTable is statically available, and assigned to within the Application_Start event of your global.asax. When a request comes in the table is traversed and the first match found is used. For more info see the bottom of the page for a mini routing guide

One key difference here is that instead of using regular expressions the url is defined by a tokenized string. This meant that it was possible that my pagination and details routes would clash i.e. {controller}/{action}/{page} and {controller}/{action}/{detailsuri}. To avoid this I had two options:

Constraints (IRouteConstraint)
The MapRoute method takes an object with corresponding IRouteConstraints per route parameter. This means I could do something like:
routes.MapRoute("DefaultWithPage", "{controller}/{page}", new { controller = "Blog", action = "index", page = 1 }, new { page = new IntegerConstraint() });
An IntegerConstraint may then look like: public class IntegerConstraint : IRouteConstraint { public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) { string value = values[parameterName].ToString(); int parsedInt = 0; return int.TryParse(value, out parsedInt); // True if the value is an integer } }
Constraints (regex string)
The IRouteConstraint is fine but could perhaps be seen as overkill. Rather than unnecessarily creating a whole new class implementing IRouteConstraint we can instead pass regular expression strings such as: routes.MapRoute("DefaultRootWithPageAndFormat", "{page}", new { controller = "Blog", action = "index", uri = "" }, new { page = "[0-9]+" });

The much more concise approach of the regex was appropriate here. However constraints can be useful for other more complicated scenarios.

Useful IRouteConstraints

IRouteConstraints could provide an injection point for user defined shortcut checking, such as when '/septemberdeals' is created as a shortcut to the longer '/shop/discounts/2009-09' url. This could easily be a CMS requirement:

"The user can create on the fly direct links for publication or promotion purposes - for example '/septemberdeals' resolves to '/shop/discounts/2009-09' and so on."

Of course, a short url would normally map to a default controller route e.g. '/{controller}' with '/septemberdeals' trying to find a 'SeptemberDeals' controller.

So how about a Constraint that when it receives a request goes away and compares it to a list of known shortcuts (hopefully stored in memory at this point rather than incurring a database hit) returning false if none exist, allowing the route engine to continue down to the less specific '/{controller}' route. When a shortcut is found the route will match and the later '/controller' route will not be compared - avoiding an error when the 'septemberdeals' controller is not found.

I had a similar issue for cargowire, the main content mapped well to useful controllers. It was clear that an articles controller would be useful. It could interact with an articles service/respository layer and manage listings and details views based on the data. However some pages such as 'notes' were text content written directly to file, with arguably no real need for a full controller class.

On the prior version of cargowire I had a 'notes.aspx' and 'xsl.aspx' page that did nothing more complicated than output some words I had hard written straight in. To perform this action in the MVC version I made use of a FromValuesConstraint:

/// /// Originally sourced from: http://blogs.microsoft.co.il/blogs/bursteg/archive/2009/01/11/asp-net-mvc-route-constraints.aspx /// public class FromValuesListConstraint : IRouteConstraint { private string[] _values; public FromValuesListConstraint(params string[] values) { this._values = values; } public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) { // Get the value from the RouteValueDictionary string value = values[parameterName].ToString().ToLower(); // Return true is the list of allowed values contains this value. return ((IList)_values).Contains(value); } }

This enabled me to create a PageController that merely output a view directly by name. The FromValuesListConstraint could then guarantee that the route only matched when there was a 'hard written' view to be found.

I could either put the FromValuesListConstraint on the '/{controller}' route with a list of known controllers, or on the PageController route with a list of the 'hard written' views. I ended up opting for the former, allowing me to easily add hard written views ad hoc without the need for a recompile. However I could just have easily done it the other way round, or implemented a more complex constraint such as one that used reflection to identify the list of controllers available or that read the view directory to find available views.

Conclusion

Constraints allow for powerful methods of route matching, far in excess of the limitations of using only regex for matching. By introducing code into the mix, in the form of constraints, any number of application scenarios can result in a route matching or not matching. A helpful resource when doing this is Phil Haack's Routing Debugger tool that allows for easy testing of routes including applying any associated constraints (see the related links below).


N.B. Mini MVC Route Guide

Routing in MVC works in the following way:

  1. Routes are defined in code and added to the static route collection
  2. When a url is requested the route table is traversed. The first route that matches is processed.
  3. The 'controller' parameter, by convention, maps to the instantiation of a controller class that should exist in your code e.g. a route '{controller}' with a request '/blog' would lead to the instantiation of a 'BlogController' class.
  4. The 'action' parameter, by convention, is used to call the appropriate method on that class with the remaining route parameters matching up to the methods parameters e.g.
    RouteRequestMatches
    {controller}/{action}/{page}/blog/index/2 The Index method of the BlogController, passing 2 as the int page parameter
  5. The defaults allow certain parts of the route to be missing e.g.
    RouteDefaultsRequestMatches
    {controller}/{action}/{page}defaults = new { action = "index" }/blog/2Will also match the '{controller}/{action}/{page}' and the BlogController index method
backback to top]]>
Xml Explicit Always Sucks http://cargowire.net/articles/xmlexplicitiseasy http://cargowire.net/articles/xmlexplicitiseasy Craig Thu, 05 Nov 2009 20:15:00 GMT You and I both know that if you ever venture into the world of SQL Server's XML explicit, you usually end up regretting it. So here's a brief example of how it works.. just to refresh your memory. SQL Server's Xml Explicit has always managed to annoy me. It's one of those things you don't do often enough to have it solidified in your mind... So here's a quick example to refresh both yours and my mind:

1) Simple Database

Contributor
PKContributorIdint
Namenvarchar(50)
Nicknamenvarchar(50)
ContributorEmail
PKContributorEmailIdint
FKContributorIdint
Emailnvarchar (1024)
ContributorUrl
PKContributorUrlIdint
FKContributorIdint
Urlnvarchar (2048)

2) Syntax Recap

Most examples talk about the resultset order being important, and we'll address that, but lets recap the syntax first. A simple query for XML explicit could be:

SELECT 1 as Tag, NULL as Parent, NULL AS [contributors!1], NULL As [contributor!2!id], NULL As [contributor!2!name], NULL as [contributor!2!nickname], FROM Contributor As contributor UNION SELECT 2 As Tag, 1 as Parent, NULL AS [contributors!1], contributor.ContributorId As [contributor!2!id], contributor.Name As [contributor!2!name], contributor.Nickname as [contributor!2!nickname], FROM Contributor As contributor -- Outputs (without For Xml Explicit) -- ======== -- Tag Parent -- 1 NULL NULL NULL NULL NULL NULL NULL NULL NULL -- 2 1 NULL 1 C Rowe Craig NULL NULL NULL NULL -- 2 1 NULL 2 M Pike Matt NULL NULL NULL NULL

Each query being unioned represents a single element in the eventual xml heirachy. 'Tag' and 'Parent' are mandatory for SQL Server to identify the structure you intend to create for your xml document. The other items in the select list are used for each node name, it's attributes and child nodes. All nodes and attributes need to be represented in the full resultset so they each need to be referenced in all unioned queries (even as null on the nodes that don't require them).

The names of the resultset columns are used to parse the normal table output into an XML document. In brief:

  • The names are enclosed in square brackets.
  • The name of the element is first, separated by an exclamation mark, followed by the node number.
  • This is then optionally followed by another separator before the attribute name.
  • The attribute name can optionally be followed by !element to force it to show as a child element rather than an attribute or !hide to hide from results (useful for sorting).
  • !!cdata can be used to declare an item as cdata.

So, in fig 2.0 above, Tag 1 has no parent and it's element name is 'contributors'. A second tag is declared as 'contributor' with three attributes id, name and nickname. These results are nested so tag 2 is within tag 1 (if there were a tag 3 it would be within tag 2).

The Ordering

The important thing to ensure is that as you look down the resultset the row above the current row either has the same Parent value (is a sibling element) or has as its Tag value the Parent value of below (is the parent node). An incorrect order will result in the following error:

Parent tag ID is not among the open tags.

Desired Output

The XML we want from the database is (comments indicate tag numbers in relation to the query below):

<contributors> <!-- This is tag #1 --> <contributor id="1" name="C Rowe" nickname="Craig"> <!-- This is tag #2 --> <urls> <!-- This is tag #3 --> <url>http://cargowire.net</url> <!-- This is tag #5 --> </urls> <emails> <!-- This is tag #4 --> <email>[email protected]</email> <!-- This is tag #6 --> <email>[email protected]</email> <!-- This is tag #6 --> </emails> </contributor> <contributor id="2" name="M Pike" nickname="Matt" /> <!-- This is tag #2 --> </contributors>

Notice the node numbering increments for each differently named node and for each indentation i.e. no tab indent has one distinct element name (contributors) this is node 1. Single tab indent has one distinct name (contributor) and so is node 2. At two levels of indent 'urls' and 'emails' become node 3 and 4 respectively leaving three indents in 'url' and 'email' to be 5 and 6.

Query

The query below can be used on the above database to display the desired output. There may well be a more succinct way of doing this, but I like the readability.

-- Section 1: Outer select allows for ordering at end SELECT Tag, Parent, [contributors!1], [contributor!2!id], [contributor!2!name], [contributor!2!nickname], null as [emails!3], null as [urls!4], [email!5], [url!6] FROM ( -- end section 2 -- Section 2: Create the overall parent element named 'contributors' -- This has null values for all other fields as it has no attributes SELECT 1 as Tag, NULL as Parent, NULL AS [contributors!1], NULL As [contributor!2!id], NULL As [contributor!2!name], NULL as [contributor!2!nickname], NULL As [emails!3], NULL As [urls!4], null AS [email!5], null AS [url!6] FROM Contributor As contributor -- end section 2 UNION -- Section 3: Select all the contributor nodes with attributes -- for id, name and nickname SELECT 2 As Tag, 1 as Parent, NULL AS [contributors!1], contributor.ContributorId As [contributor!2!id], contributor.Name As [contributor!2!name], contributor.Nickname as [contributor!2!nickname], NULL As [emails!3], NULL As [urls!4], NULL As [email!5], null As [url!6] FROM Contributor As contributor -- end section 3 UNION -- Section 4: Create 'emails' container nodes, inner join to ContributorEmail to ensure -- no 'emails' container if no 'email' nodes to fill it later SELECT 3 As Tag, 2 as Parent, NULL AS [contributors!1], contributor.ContributorId As [contributor!2!id], contributor.Name As [contributor!2!name], contributor.Nickname as [contributor!2!nickname], 'emails' As [emails!3], NULL As [urls!4], NULL As [email!5], null As [urls!6] FROM Contributor As contributor INNER join ContributorEmail AS email on Email.ContributorId = contributor.ContributorId -- end section 4 UNION -- Section 5: Create 'urls' container nodes, inner join to ContributorUrl to ensure -- no 'urls' container if no 'url' nodes to fill it later SELECT 4 AS Tag, 2 as Parent, NULL AS [contributors!1], contributor.ContributorId As [contributor!2!id], contributor.Name As [contributor!2!name], contributor.Nickname as [contributor!2!nickname], NULL As [emails!3], 'urls' As [urls!4], NULL As [email!5], null As [url!6] FROM Contributor As contributor INNER join ContributorUrl As url on Url.ContributorId = contributor.ContributorId -- end section 5 UNION -- Section 6: Select all email nodes with the 'emails' tag as parent SELECT 5 AS Tag, 3 as Parent, NULL AS [contributors!1], contributor.ContributorId As [contributor!2!id], contributor.Name As [contributor!2!name], contributor.Nickname as [contributor!2!nickname], 'emails' As [emails!3], NULL As [urls!4], email.Email As [email!5], NULL As [url!6] FROM Contributor As contributor INNER join ContributorEmail AS email on Email.ContributorId = contributor.ContributorId -- end section 6 UNION -- Section 7: Select all url nodes with the 'urls' tag as parent SELECT 6 AS Tag, 4 as Parent, NULL AS [contributors!1], contributor.ContributorId As [contributor!2!id], contributor.Name As [contributor!2!name], contributor.Nickname as [contributor!2!nickname], NULL As [emails!3], 'urls' As [urls!4], null As [email!5], url.url As [url!6] FROM Contributor As contributor INNER join ContributorUrl As url on Url.ContributorId = contributor.ContributorId -- end section 7 ) as Contributors -- Section 8: By Ordering by contributor id followed by emails and urls we ensure -- the correct order to avoid the 'parent tag is not among the open tags' problem ORDER BY [Contributor!2!id], Contributors.[emails!3], Contributors.[urls!4] FOR XML EXPLICIT

Table resultset

Note the ordering of the Tag and Parent columns and the way the 'emails' and 'urls' columns can be used to assist this ordering
TagParent[contributors!1][contributor !2!id][contributor !2!name][contributor !2!nickname][emails!3][urls!4][email!5][url!6]
1NULLNULLNULLNULLNULLNULLNULLNULLNULL
21NULL1C RoweCraigNULLNULLNULLNULL
42NULL1C RoweCraigNULL ('urls')NULLNULLNULL
64NULL1C RoweCraigNULL ('urls')NULLNULLhttp://cargowire.net
32NULL1C RoweCraigNULL ('emails')NULLNULLNULL
53NULL1C RoweCraigNULL ('emails')NULL[email protected]NULL
53NULL1C RoweCraigNULL ('emails')NULL[email protected]NULL
21NULL2M PikeMattNULLNULLNULLNULL

Final Thoughts

Xml Explicit is particularly powerful and is often the easiest course of action if a service is designed with Xml in mind. However it can lead to large complex queries. Users should consider the use of temporary tables if multiple unions occur on laborious queries.

]]>
Why .NET MVC? (and why should we care?) http://cargowire.net/articles/whydotnetmvc http://cargowire.net/articles/whydotnetmvc Craig Tue, 18 Aug 2009 13:00:00 GMT An intro and brief take on .NET MVC and what it means particularly in reference to WebForms. Having previously written about the highs and, perhaps more importantly, lows of working as a .NET developer. This article will continue the trip into Microsoft World, only this time it’s to the land of MVC.

Recently Microsoft was brought back to the attention of many, not just for the interestingly named Bing, the Yahoo ‘partnership’, or the delights of a browser choice screen. Developers with their ear to the Redmond ground became aware of something being touted as the next big thing for Microsoft .NET development – ‘MVC’.

Although announced some time ago many users left it aside until a more complete release. Now however, with another release on the horizon and many examples of sites that use MVC (including the particularly well known StackOverflow) it is certainly something people are using on a daily basis.

As would any eager developer I tried the beta, had fun installing the final release and have now been involved working with and using it. My impressions so far are good. It would appear that Microsoft have addressed those amongst us bemoaning the issues of WebForms. For example lets take a look at a collection of comment snippets from the “don’t hate me post”:

Markup

When I first tried the winforms model after being a ASP developer for many years part of me loved it’s rapid development but I always felt a bit dirty when looking at the source code... Chris Morledge

A key point really here is that the abstraction that was provided by .NET webforms was/is, for some, a step too far. The masking of actual html output behind server controls, although rapid, caused friction between backend and front end developers. A carefully crafted html design would often be bounced back and forth as developers implemented using controls.

Conversely MVC is far closer to the metal in terms of both your html and indeed your required knowledge of the way the web works. Although views are often output with html helpers these are far easier to customize than creating your own Custom Control Adapters. With .NET MVC, webforms Developers will be reminded that there is no inherent state on the web (and perhaps hopefully of the separation between back and front end development - I've never been a fan of auto-generated javascript. It can lead to an over reliance and ignorance of approaches like hijax).

Tutorials Available

All of the training material and tutorials will show you how to do it the easy way Tim Snadden

This has been an issue I've had with some Microsoft materials for a long time. Reading about things like <asp:SqlDataSource /> controls always left a bad taste in the mouth in terms of reusability, testability and layered architecture. However, some of the materials on the MVC site are bucking that trend.

Working around .NET

we crafted our own pseudo MVC framework cmv

Similarly to cmv many devs have crafted their own implementation to separate presentation and logic concerns. I have previously discussed using XML and XSL for this. However now we don't have to, or if we do want to with .NET we can at least work from an open source framework (yes MVC is on an open license) with a multitude of available view engines or even create our own view engines.

Seemingly few people who dislike the idea of using Microsoft technologies are aware of the Mono Project. An open source .NET implementation with an IDE (Mono Develop). For those of you who would like to know more I thoroughly recommend Miguel de Icaza's appearance on the stackoverflow podcast. Mono is also not as open to legal attack from Microsoft as people may think.

So how is it done?

There are already many resources for learning .NET MVC, not least the asp.net/mvc site itself. In brief a project will contain:

Views - Implementing IView (guaranteeing a Render() method)

The default MVC project from Visual Studio includes a number of sample views. These are instances of the ViewPage class. Data can be passed to these views by the controller through the ViewData property bag. However if you change the type to ViewPage<T> these views become typed views. For example you may have a 'CustomerViewModel' object (encapsulating view related information for a Customer entity/Customer BO) and so create a ViewPage<CustomerViewModel>. In this case the View has access to a ViewData.Model which will be a typed customer view model instance.

In terms of team breakdown these '.aspx' pages will be where the html is and where designers may wish to make their mark.

<%@ Page="" Title="" Language="C#" MasterPageFile="~/Views/Shared/Cargowire.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable <BlogPost>>" %>
Controllers - Implementing IController (guaranteeing an Execute() method) or generally inheriting from the Controller class
The Controllers job will be to direct the traffic based upon the request, including processing actions (using methods that return ActionResult) that map to the 'action' url part. // GET: /Home/ public ActionResult Index() { ... // e.g. Commands to return an IEnumerable<BlogPost> return View(blogPosts) // returns ViewResult(IView) (Ultimately inherited from ActionResult) }
Models - Component(s) for maintaining state
Models can take many forms including business objects mapped to sql through linq to sql or of course a number of layers including services, repository and business object classes.
Routes defined in Global.asax
routes.MapRoute( "Default", // Route name "{controller}/{action}/{id}", // URL with parameters new { controller = "Blog", action = "Index", id = "" } // Parameter defaults );

The Process

Figures 1.1 - 1.3 illustrate a simple example using .NET MVC. In this example a route has been defined for the blog controller and the action 'Index'. When a site visitor hits 'http://site.com/blog/index' the .NET MVC Framework will invoke the Blog Controller's Index method. This method will ultimately retrieve an IEnumerable<BlogPost> instance which can then be displayed within the typed view. For example the view content could be:

<% foreach (var post in Model) { %> <div> <h2><%= ViewData.Model.Title %></h2> <p><%= ViewData.Model.Body %></p> </div> <% } %>

In this simple example the BlogPost class is a business object that could well map directly to a persistant storage entity. However in a more fleshed out system it could be that the View is typed to a 'BlogPostsViewModel' that contains items that can be enumerated for listings, plus items for category description etc.

Final Thoughts

This article has attempted to do two things. Firstly to act as a sequel to "Don't Hate me for my .NET" but secondly to introduce, at a basic level, .NET MVC. The example given is to provide a flavour of MVC development on the .NET platform and could be expanded to cover a number of other currently favoured approaches and technologies including more detailed assessment of the Model and how the dependencies interact. However, that may be for another day.

The community around .NET MVC is already thriving with a plethora resources, many of which I have linked to when possible above.

]]>
Ubuntu gets inside Windows http://cargowire.net/articles/seamlessubuntuwindows http://cargowire.net/articles/seamlessubuntuwindows Craig Sun, 09 Aug 2009 16:15:00 GMT A run down on my experiences of getting my pre-existing Ubuntu install to run inside VirtualBox on vista. Some time ago, after building my PC and getting rather hard drive happy, I set up an install of Ubuntu on a dual boot (for all that native linux work I do...). However I soon found that going back and forth between the two was putting me off making any active use of it. And so the quest began...

Ok, so not really a quest but I did want to get to my ubuntu/vista holy grail:

The above is a screenshot of my current set up. Running Vista natively I use Sun's Virtual Box to access and use the Ubuntu install that I had previously been separately booting into. This means I can avoid any migration of data from the separate disk into a VHD and I can still boot into Ubuntu natively if I need to. In seamless mode I can even play around and make screenshots like the above where IE sits above an Ubuntu Firefox

Step 1 (implied): Dual Boot Ubuntu and Vista

Install Ubuntu onto a separate drive and get it to dual boot (Download Ubuntu, create bootable disk, install to new drive, setup booting etc). Depending on how you set it up you may find Easy BCD a useful app (if you end up wanting to frig with the windows Boot Loader).

Step 2: Download and Install Virtual Box

Nip over to Virtual Box and bag yourself a copy - currently 'VirtualBox 3.0.4 for Windows host'.

Bearing in mind the joy of Vistas UAC you may need to run this as admin.

Step 3: Read the documentation - get scared

Page 134 of the version 3.0.4 user manual describes the use of a complete physical hard disk as the source for the guest operating system.

Apart from scaring the bejesus out of you with talk of corruption and loss of data it identifies that you need to create a VMDK file and assign it to a virtual machine.

Step 4: Creating a VMDK file

Section 9.10.1 provides us with the following code (to run in a dos command window - that is again being run as admin):

VBoxManage.exe internalcommands createrawvmdk -filename /path/to/file.vmdk -rawrisk /dev/sda

This will create a vmdk file named 'file.vmdk' from the disk '/dev/sda'. Ultimately the example code translates for us 'Vista hosting Ubuntu' folk to something like:

C:\Program Files\Sun\xVM VirtualBox>VBoxManage.exe internalcommands createrawvmdk -filename C:\Tools\ubuntu.vmdk -rawdisk \\.\PhysicalDrive2 -partitions 1,5 -register

Note that two partitions are included in my VMDK creation script - unlike the example code. The user manual doesn't include partition specifiers. However if you need to do so you can identify the partition numbers using the following command:

C:\Program Files\Sun\xVM VirtualBox>VBoxManage.exe internalcommands listpartitions -rawdisk \\.\PhysicalDrive2

This will result in a screen similar to below (you can see where I got 1,5 from for my createrawvmdk command):

PhysicalDrive2 in the createvmdk command is in reference to the fact that my machine was/is running 3 HDs (Windows (0), Data (1), Ubuntu (2)).

Step 5: How am I going to make it boot?

The easiest way to boot the system is to create a bootable CD and mount that as part of the virtual machine startup. To create this, first boot into your Ubuntu install.

Gnu.org then provides a succinct description on how to create a bootable grub CD:

  • Create a place to store your source files for the bootable disk ([home folder]/iso/boot/)
  • Copy the 'stage2_eltorito' file from '/usr/lib/grub/i386-pc/stage2_eltorito'
  • Copy the menu.lst file from '/boot/grub/menu.lst'
  • Or just run: ~$ mkdir iso ~$ mkdir -p iso/boot/grub ~$ cp /usr/lib/grub/i386-pc/stage2_eltorito iso/boot/grub

At this point you may wish to edit the menu.lst file. My original menu.lst file included menu options for Ubuntu and Vista. As the boot would be occuring within the VM with knowledge only of the physical disk I was booting in to I had to adjust the menu items. Removing the vista related boot options and changing the ubuntu options to use (hd0,0) instead of (hd2,0).

An ISO can then be created using mkisofs as below (assumes [home folder]/iso/boot as the location of the copied stage2_eltorito and menu.lst): ~$ mkisofs -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -o grub.iso iso

For more information on the mkisofs command check out the man page. In short:

  • -b signifies an El Torito bootable media is being created from the path 'boot/grub/stage2_eltorito' (relative to the source path - the 'iso' at the end of the command).
  • -o signifies the filename of the iso output (grub.iso).
  • -no-emul-boot is included as this is not a floppy image
  • -boot-load-size 4 is recommended for backwards compatibility as some OS's will have problems if it is not a multiple of four

Before returning to Ubuntu copy the ISO to somewhere accessible to windows (either direct to a shared HD or temporarily on to a USB etc).

Step 6: Start it up

Back in vista you should now be able to open up VirtualBox (running as admin to avoid permissions errors on disk access).

  • Create a new virtual machine with whatever name you like as Linux Ubuntu
  • Choose an allocation of Memory. I opted for 512MB of my total 4GB
  • Choose 'use an existing hard disk' and select the VMDK file you created earlier
  • Once created open the settings for the new virtual machine and choose 'CD/DVD-ROM'
  • Choose to Mount an ISO image file and choose the ISO you created within ubuntu
  • Ensure the boot order under 'System' has CD/DVD-ROM above Hard Disk
  • Start the Virtual Machine

Step 7: Ok so I'm in.. but the resolution is tiny

The first thing I noticed when I entered the VM was that I had a very low resolution and was unable to resize the window larger. This may not be an issue for you. However if, like me, it was then you need to install VirtualBox Guest Additions.

Using the 'Devices -> Install Guest Additions' option on the VBox window attempts to mount the Guest Additions install as a CD within Ubuntu. However when I tried this it kept getting confused between the grub.iso and the disk I was trying to mount. Rather than faff around too much I found it easier to do the following:

  • Copy the VBoxGuestAdditions.iso from C:\Program Files\Sun\xVM VirtualBox\ to somewhere accessible by Ubuntu (either USB or direct to the ubuntu drive from windows while VBox is closed and before booting normally in to ubuntu).
  • Within Ubuntu use something like gISOMount or simply extract the contents of the ISO
  • From the command line navivate to the extracted/mounted folder and run: ~$ sudo sh VBoxLinuxAdditions-x86.run
  • Back into windows and start up your VM - you should find that you can now resize to your hearts content. Choosing 'Machine -> Seamless Mode' will allow you to run Linux and Vista windows side by side as in the first screenshot.
]]>
Don't hate me for my .NET http://cargowire.net/articles/donthatemeformydotnet http://cargowire.net/articles/donthatemeformydotnet Craig Sat, 02 May 2009 17:30:00 GMT A quick airing of my thoughts on .NET after plenty of discussions with haters and lovers alike. I'm an outcast trying to fit in... at an event like FOWA I'll feel like working with .NET is akin to admitting to owning the Rednex single 'cotton eye joe' from the glory days of '94... but then I'll go to a Microsoft event and feel like a pariah obsessed with miniscule details that I shouldn't worry about (unobtrusive javascript.. element ID and exact markup control...).

A generalisation this may be but it highlights the difference in perception between languages such as PHP/Ruby and .NET in the world of web. So much so that people often don't even list .NET when they reel off examples after the phrase 'your language of choice'.

I don't so much want to 'put the record straight' just to put forward my experience starting out with PHP and moving to .NET, with a sprinkling of the stuff I usually hear against .NET.

Background

Following a pretty standard path I started out in web development with static HTML, moved on to being scared by CGI then dabbling with javascript and later some PHP and Actionscript (with some VB6 and Java studying thrown in there for good measure too). This led to my first full time role being as a PHP developer, which later evolved into a C# position.

.NET WebForms vs. Everyone Else

The first thing I (and many others) realise when moving to .NET (Webforms) is that it's really not the same paradigm. In fact I'd go so far as to say that if you skipped straight to learning Webforms, you haven't learnt web development. What you've learnt is winforms. And the reason for this is that that was the intention of Webforms - to assist winforms developers in making the leap to the web and to mask the lack of state.

The 'innovation' therefore of postback/viewstate persisted server controls was that as a developer you didn't have to worry about working in a stateless environment as you did with other languages. Nor did you really have to worry about the actual markup output (in the same way that you wouldn't worry about how the pixels rendered for a button in a windows app). Submit buttons and Select boxes can have server side Click and IndexChanged events and before you know it you're well away without worrying about html or javascript or even css (if you went with some rather questionable attributes available on server controls for presentation).

What this caused however was a largely negative view of .NET from the non .NET side of the tracks, and it's generally the sort of stuff I continue to hear.


However this is not an attack on .NET (whether people know it or not). This is an attack on a particular way of coding in .NET webforms. Yes, Microsoft pushed .NET to be used in those kind of ways but that doesn't mean you had to do it that way.

In the same way that developers don't use the visual interface of Dreamweaver to generate their markup .net developers don't need to use server controls and viewstate. Just because it's there and assists some people in their needs doesn't mean everyone should use it.

Much of my recent work for example has relied heavily on generating Xml as the content and using Xsl to create the presentation, thus bypassing the majority of asp.net server controls and their associated scripts/viewstate/long ids.

Without taking this approach you can still make your own user and custom controls, but be smart about how you make them. Turn off viewstate when not needed, use standard html controls when you don't need the functionality provided by an asp server control and use repeaters with your own standard html templates rather than .NET rendered gridviews.

.NET or not .NET?

It could be argued that doing these kinds of things is not '.net' but thats not true. It may not be entirely '.net webforms' but you are still using the power of the .net frameworks class library. You are still using the, in my view currently unchallenged awesomeness of, Visual Studio (and yes I've used eclipse.. it's not as amazing as you might like to think) and you're still getting the ability to write in the same language for your website, windows services, silverlight, xbox and windows applications.

Admittedly it's unfortunate how long it has taken for the release of asp.net MVC (although lets be honest PHP weren't flying off the blocks with full and complete OO support so no-ones perfect). However the key is, as with so many things, that the quality of your .net output is down to the quality of the development.

Wrap up

I too, when I was asked to swap to .net from PHP, thought .net was an overcomplication. "I want to just call the database and do a loop outputting html in my markup. I don't want to put a GridView in the markup then in a 'code behind' 'load event' access the database and databind to the grid".

It's a leaning curve as with all things. My early PHP was, going back on it, messy to read and understand as it was all mixed in with markup with include files all over the place. Similarly my early .net work probably relied on an overuse of server controls. As you get in to something you get better at it. And although .NET seemed like a greater move away from static pages than PHP (which is probably why I saw it as an overcomplication) I now personally love working with it.

I'll wrap this article up briefly with some reasons I like .net that either I haven't found at all, or have found harder to do in other environments/languages.

  • Similar syntax to java/javascript/actionscript
  • Reusable classes across web applications, windows applications, windows services, IIS modules, xbox games
  • Very easy to cache with a large variety of inbuilt assistance
  • Extremely OO friendly

I'm not saying .NET is the best, or amazing, but its certainly not something to be looked down upon or avoided purely because it's Microsoft or because of a misunderstanding surrouding it. Over the time I've been using it it's got better and although the picture I paint in the intro to this article is still true, it is less so nowadays. Css Control Adapters have been around a long time to assist with poor rendering, MVC is upcoming, and along with things like ClientID mode the bad things are going or easily avoidable.

I'm not sure I've covered everything I would have wanted to in this post, as it is such a vast area and this was really just a one sided conversation from the POV of .NET not being quite as sucky as many people think. Please fire any points gripes or questions at me.


Mini Glossary (for those .net virgins among us)

One form to rule them all
Webforms asserts that each page has one form that contains all elements rather than multiple forms as and when necessary. Or to quote...
For example, most ASP.NET Web pages contain a single server-side Web Form, with multiple Web controls inside the Web Form. The Web Form is an HTML control (System.Web.UI.HtmlControls.HtmlForm). Those Web controls inside the Web Form are children of the Web Form.
Postback
Form field data is posted to the server and used to repopulate form field values automatically e.g. if you change an instance of a textbox server control before posting back .net maintains the value you posted from the first screen. Similar to the following manually achieved effect in PHP: <textarea name="body" id="body" cols="40" rows="5"> <?php echo htmlspecialchars(stripslashes($_POST['body'])); ?> </textarea>
Viewstate
The encoded (and optionally encrypted) first hidden field used by .NET as a means to persist programatically set control properties. <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTMwMTcxNDUyNmRk4HWhWoozWLYUelHWkPH2E67bXGo=" /> A control will gain its final value after the following cascade: Initial declarative value, Posted value from Request.Form (if postback), ViewState value (if changed via code after a postback).
Crazy IDs
Until the upcoming 4th version of .net developers were not trusted to know if there server control IDs were unique and because the built in viewstates, postbacks etc relied on it someone decided to make damn sure that control IDs were unique and context based on their location in the control heirachy. This led to ids like "ctl00_asp_menu_links_ctl03_contextLink". Which, if someone added a parent or reshifted markup slightly, would change. Particularly helpful for clean client side development.
]]>
Our First AIR App http://cargowire.net/articles/ourfirstairapp http://cargowire.net/articles/ourfirstairapp Craig Fri, 13 Feb 2009 15:00:00 GMT A Boagworld post on the experiences of Dave McDermid and I in creating a simple AIR application. Why you should make your own site http://cargowire.net/articles/whyyoushouldmakeyourownsite http://cargowire.net/articles/whyyoushouldmakeyourownsite Craig Sun, 30 Nov 2008 14:30:00 GMT A developers view: Thoughts on the benefits of starting from scratch Many people spend time creating a personal website but what really is the point?

Unless it is your base of operations for freelance work or tightly linked to your company profile it may be just an exercise in narcissism. However that doesn't have to be the case. It is my firm belief that the main purpose of having a personal website is to create it yourself.

If you are a designer you may opt to use an open source blog but spend time creating your own skin/template. If you are a developer you may download one of the many free design templates and code functionality for yourself. The point is that you do some of the work yourself.

But there's so much already out there

OK, so this can mean you 'reinvent the wheel' but is this necessarily a problem? A personal site is probably the only place where you have total free reign in terms of design/content and functionality, so it is your place to experiment and try new things. Yes you could install an off the shelf blog with various plugins and set it up in a day, but that's not going to help you. It will only help your susbcribers (if you even have any at this point ...and if you write any decent content). Why should your personal site be focussed only on the readers. You, the author, should take something from it.

Jeffrey Zeldman has written about content outsourcing causing the disappearance of the personal site. This may be very true, and why not, if you want to host images flickr provides a great place to do that. If you want to store your bookmarks online delicious is excellent. You can even get plugins for blogs and browsers. But what do you personally learn from that?

With this site I have used third party services. My links are from delicious, my status is from twitter and my location is a combination of brightkite and google maps. But instead of just plugging this into a blog platform I have dealt with all the code myself. Crazy maybe? A waste of time? but definately a good learning experience. Did I do this because I really thought people cared where I was? or what I'd just said on twitter? No. Particularly as a young developer I need to keep up to date and 'hone my skills' and I was able to explore the use of restful apis, caching, providing multiple response content types and much more.

How would a free blog install with other developers plugins have helped me? Maybe I could get involved with developing plugins myself? but I would be restricted by user need, platform etc. It may even be a big jump to get to a public plugin release standard of code, especially if you are just starting out.

That is not to say you shouldn't participate in a community. A conference doesn't go by without speakers espousing the benefits of such activity.

So why do it?

Developing your own system is outside of the constraints of work (where platform or versions may be restricted) or even other peoples needs (where you can't just do something to learn a technique, it must have a purpose). It is your sandbox for you to create and recreate.

There are further benefits... you may want to blog (after all everyone's doing it). What are you going to write about? Maybe you're a student or your employed work is under confidentiality agreements? Time spent building, experimenting and updating your personal site is an excellent source of content. And it's based on real life development (not trivial examples) to explain something you've learnt or read about recently.

Conclusion

Spending time developing your own site gives you the chance to try knew things, reinvent how you did them before, and make use of things you may not yet need for clients or work but might do in the future. It is a real project that is live that needs to be treated as such and yet at the same time is totally within your control.

Code you write can be ported almost immediately into blog posts describing your process without fear of breaking confidentiality or forcing your explanations into trivial examples.

Personal sites often cover multimedia, feeds, downloads, interaction with visitors, interaction with web services. Almost any knew technique can be applied in some way, giving you the chance to learn in a non time pressured environment at your own pace on a real live project.

A personal site should help you as well as your visitors.

Catch me on twitter with your thoughts.

]]>
Cheap Scheduling with Cache Expiration http://cargowire.net/articles/cacheexpirationscheduling http://cargowire.net/articles/cacheexpirationscheduling Craig Sat, 25 Oct 2008 21:00:00 GMT Need scheduled activities but don't or can't create a service? Often there's a need to do some activity independent of page requests. Windows service creation or even old school vbscript task scheduling can provide the answer. However there is another way...

When building this site I always intended to hook into an abundance of APIs. Already on this site delicious, twitter, brightkite and google maps can be seen. However with their usage comes a number of issues.

Continuing with the cargowire example, if a user were to hit the interesting links page they would be requesting information from Twitter for the header status, Delicious for the links and brightkite + google for the map under the nav. This of course is all wrapped up in the request for images/css/content direct from cargowire.

Caching is the Answer

The obvious approach therefore is to cache the api responses. This not only helps in terms of speed of page response but also avoids breaking any api limits on requests if your site gains a lot of attention.

In the example below I'm using a static property as the accessor to a cached XPath document. RandomApi is merely a placeholder for what could be any API wrapper (twitter etc) that returns the XML after accessing the web service.

private static XPathDocument CachedXPath { get { XPathDocument xpathCache = HttpContext.Current.Cache[CacheKey] as XPathDocument; if (xpathCache == null) { xpathCache = new RandomAPI(ConfigSettings.RandomAPIUsername, ConfigSettings.RandomAPIPassword).ToXML(); HttpContext.Current.Cache.Add(CacheKey, xpathCache, null, DateTime.Now.AddMinutes(ConfigSettings.RandomAPITimeoutMinutes), Cache.NoSlidingExpiration, CacheItemPriority.Default, null); } return xpathCache; } }

The code implements a relatively well used pattern whereby the cache item is attempted to be accessed, if available it is returned, if not it is created and put in the cache for the next request. The cache expiration is absolute to ensure that no matter the frequency of visitors the cache will expire at regular intervals (ensuring up to date content is retrieved from the web service). If sliding expiration was used the cache may never expire as each visitor restarts the timer.

Problems with Caching

However even caching has its problems, particularly if your site has low regularity of traffic. Consider the following example:

  1. A user hits your site.
  2. The site requires delicious, twitter and brightkite but no-one has been to the site since the last cache expired.
  3. All three are requested from the relevant services and stored in the cache for the next user. An expiration time is set for each so that they are kept up to date (for example 5 minutes for twitter or maybe a day for delicious).
  4. No user comes within the expiration time.
  5. A user comes after the expiration time - the cache is useless as it's non existant - so all items are requested again meaning the user has to wait for delicious, twitter and brightkite before getting their page. Your caching strategy has given no real benefits.

Scheduled caching is the real answer

Ideally then what is needed is a scheduled job that refreshes the cache independently from the page requests. So that when a page request comes in the cache is already there and the server can respond immediately...

At the point of considering some kind of cron job or windows scheduled task/service we should probably stop and take a step back.

In my view it's best to keep things within asp.NET if possible. Not necessarily for a specific technical reason but why skip out of a single project if you don't need to?

Cache Expiration

If we look again at the Cache.Add function we can see a null final parameter. This parameter enables you to define a CacheItemRemovedCallback. Essentially we're talking about an event handler that is fired when the .net process removes the item from the cache.

Below is a reorganised code sample. A CacheItemRemovedCallback delegate is created and passed in to the Cache.Add function. When the cache item is removed the expiration handler is then called. If the reason is that it was invalided or expired due to time/usage then it seems viable to attempt to recreate it. If it was manually removed then you may not wish to recreate it (otherwise you don't leave yourself any option to get rid of it!). There's also the possibility of stack overflow issues with recreating a cache item after manual removal.

Essentially if you reinsert the item when the reason was 'Removed' the re-insert will overwrite the currently existing item (that is removed when this event finishes) before re-adding it. This removal will of course fire the item removed callback, which will remove/add it back again causing an infinite loop.

private static XPathDocument CachedXPath { get { XPathDocument xpathCache = WebCache.Cache[CacheKey] as XPathDocument; if (xpathCache == null) { CacheItemRemovedCallback expired = new CacheItemRemovedCallback(Expired); xpathCache = new RandomAPI(ConfigSettings.RandomAPIUsername, ConfigSettings.RandomAPIPassword).ToXML(); WebCache.Cache.Add(CacheKey, xpathCache, null, DateTime.Now.AddMinutes(ConfigSettings.RandomAPITimeoutMinutes), System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.Default, expired); } return xpathCache; } } private static void Expired(string key, object val, CacheItemRemovedReason reason) { if (reason == CacheItemRemovedReason.DependencyChanged || reason == CacheItemRemovedReason.Expired || reason == CacheItemRemovedReason.Underused) { XPathDocument xp = CachedXPath; } }

There is another difference to note. Lines 5 and 11 both reference a WebCache static class instead of the HttpContext.Current.Cache used in the first example. This is for one reason only. The cache can expire at any point during the application i.e. outside of a request for the page. This is by design, and it helps us refresh the cache without forcing a user to wait for us to do so. However there's no HttpContext outside of a page request so a call to CachedXPath will throw an exception (one that will not be seen by a site visitor but an exception none the less causing the cache refresh to fail).

One way around this is to ensure that there is a static way of accessing the application cache. An ideal time to store this is before there is any possibility that the cache will be requested. By simply adding a few lines to the Global.asax a static variable can be set for use throughout the application.

protected void Application_BeginRequest(object sender, EventArgs e) { if(WebCache.Cache == null) WebCache.Cache = Context.Cache; }

[Edit] You can also make use of the HttpRuntime.Cache accessor to Cache, which will be available outside of the page request.

Conclusion

This article describes just one way to take advantage of the caching abilities of .NET. A regular refresh is valid if you need to keep data almost always in memory but regularly updated... a twitter cache that never refreshes would render it's output irrelevant.

The .NET implementation of expiration handling would allow you to run any kind of scheduled activity. Merely by calling the required function on cache item expiration, before refreshing the cache with the desired timeout you can begin and cause a pseudo timer based process.

However, using caching in this way is not always appropriate. A windows service will have higher local privileges and can be set to auto start and be manually started. The cache timeout will only begin after the first request for that cache item, and a further request will be required if the app pool recycles for any reason.

Please do catch me on twitter if you have any thoughts/feedback before I get any proper commenting online.

]]>
Dateformatting in XML http://cargowire.net/articles/dateformattinginxml http://cargowire.net/articles/dateformattinginxml Craig Sat, 18 Oct 2008 13:00:00 GMT Simple way to format dates using .net objects and xml/xslt. Formatting dates is something we do all the time and .NET provides some really easy to use methods to format based on a string. However for human readable situations we so often want the day suffixes.

Some time ago I was looking into finding a 'nice' way to format dates with the suffixes on the day i.e. 'st', 'nd', 'rd' and 'th'. I ended up coming across a Codeproject Article by Mark Gwilliam that discussed an interesting approach.

A particular point he made was:

...if you're considering adding some functionality, it's worth checking to see if you can extend the framework in some way. This allows developers to consume your code more easily and hopefully expands your knowledge of .NET along the way... Mark Gwilliam

So, with this in mind, and without wanting to extend my never ending list of usernames/passwords I decided I would just take what was discussed in the article and create my own solution based on his approach rather than download his source. The plan was to create an ICustomFormatter:

// To go from string.Format("{0:dd MMMM yyyy}", DateTime.Now); //Outputs: 18 October 2008 // To string.Format(new BritishDateTimeFormatter(), "{0:ddx MMMM yyyy}", DateTime.Now); // Outputs: 18th October 2008

This ICustomFormatter would provide a Format method that could understand the 'x' char as a placeholder for the day suffix. It would also need a way of identifying which suffix to put in its place.

An easy way to achieve this is to create an array of the suffixes referencable by the day of the month value (as below). This could also be a relatively minor algorithm to decide on suffix, it's personal preference (especially when you consider how small an effect we're talking about), but I quite like the simplicity of a static array.

namespace Formatting { /// <summary></summary> public class BritishDateTimeFormatter : IFormatProvider, ICustomFormatter { // Member containing day suffixes // Usage: extensions[dateInstance.Day]; #region Members private static string[] extensions = //0 1 2 3 4 5 6 7 8 9 { "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th", //10 11 12 13 14 15 16 17 18 19 "th", "th", "th", "th", "th", "th", "th", "tn", "th", "th", //20 21 22 23 24 25 26 27 28 29 "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th", //30 31 "th", "st" }; #endregion #region IFormatProvider Implementation public object GetFormat(Type formatType) { if (formatType == typeof(ICustomFormatter)) return this; else return null; } #endregion ... } }

Included above is also the IFormatProvider implementation. Theres nothing too complicated here, merely returning the instance as the formatter.

The ICustomFormatter implementation of the Format function can then be filled in. As you can see the short format strings are manually re-represented to ensure that they continue to work using the default behaviour. Some minor string manipulation allows the suffix to be added when and where necessary.

The default behaviour of the switch on format string is to attempt to replace the x wherever it appears in the string (except when it is escaped by a '\'. This is achieved by a cascade of formats and regex replaces that ensure that the escaped x remains as a normal x and a non-escaped x gets transformed into the appropriate suffix.

public string Format(string fmt, object arg, IFormatProvider formatProvider) { string ret = arg.ToString(); DateTime date; if (DateTime.TryParse(ret, out date)) { switch (fmt) // Switch on all single character style format rules { case "ddx": ret = string.Format("{0}{1}", date.ToString("dd"), extensions[date.Day]); break; case "dx": // Doesn't make sense to add extensions to: 08/22/2006 ret = date.ToString("d"); break; case "Dx": ret = date.ToString("D"); ret = ret.Insert(ret.IndexOf(" "), extensions[date.Day]); break; case "Fx": ret = date.ToString("F"); ret = ret.Insert(ret.IndexOf(" "), extensions[date.Day]); break; case "fx": ret = date.ToString("f"); ret = ret.Insert(ret.IndexOf(" "), extensions[date.Day]); break; case "gx": // Doesn't make sense to add extensions to: 08/22/2006 06:30 ret = date.ToString("g"); break; case "Gx": // Doesn't make sense to add extensions to: 08/22/2006 06:30:07 ret = date.ToString("G"); break; case "mx": ret = date.ToString("m"); ret = ret.Insert(ret.IndexOf(" "), extensions[date.Day]); break; case "Rx": ret = date.ToString("R"); ret = ret.Insert(ret.IndexOf(" ", ret.IndexOf(", ") + 2), extensions[date.Day]); break; case "rx": ret = date.ToString("r"); ret = ret.Insert(ret.IndexOf(" ", ret.IndexOf(", ") + 2), extensions[date.Day]); break; case "sx": // Doesn't make sense to add extensions to: 2006-08-22T06:30:07 ret = date.ToString("s"); break; case "ux": // Doesn't make sense to add extensions to: 2006-08-22 06:30:07Z ret = date.ToString("u"); break; case "Ux": ret = date.ToString("U"); ret = ret.Insert(ret.IndexOf(" "), extensions[date.Day]); break; case "yx": // Doesn't make sense to add extensions to: 2006 August ret = date.ToString("y"); break; case "x": ret = extensions[date.Day]; break; default: // Attempt a format with 'x's included System.Text.RegularExpressions.Regex addExtraEscape = new System.Text.RegularExpressions.Regex("(\\\\)(x)"); fmt = addExtraEscape.Replace(fmt, "\\\\$2"); System.Text.RegularExpressions.Regex replaceUnescaped = new System.Text.RegularExpressions.Regex("([^\\\\])(x)"); ret = replaceUnescaped.Replace(date.ToString(fmt), string.Format("$1{0}", extensions[date.Day])); System.Text.RegularExpressions.Regex removeExtraEscape = new System.Text.RegularExpressions.Regex("(\\\\)(x)"); ret = removeExtraEscape.Replace(ret, "$2"); break; } } return ret; } } }

How can I use this in XML?

By simply adding an instance method that takes the date and the format we can then add the BritishDateTimeFormatter as an extension object:

public string FormatDate(object arg, string fmt) { return Format(fmt, arg, this); }

...and call it direct from the XSL.

<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl date" xmlns:date="urn:BritishDateFormatter"> ... <xsl:value-of select="date:FormatDate(string(@time),$formatString)"/>

Conclusion

An example of this article can be found within the Links section of this site where XML is the source and a BritishDateFormatter extension object is used to format the dates using "'dx MMM \&#8217;yy'" as the format string.

This solution is obviously very british/english language specific. A further step could be to look into support for localisation.

]]>
.NET objects in XML http://cargowire.net/articles/dotnetobjectsinxml http://cargowire.net/articles/dotnetobjectsinxml Craig Sun, 12 Oct 2008 18:30:00 GMT Need to get extra functionality into your xsl transforms? Many people use XSL functions to enhance the abilities of their XML transforms. Although not everyone may be aware of a nice (and simple) way of achieving this.

XSL provides a large number of ways to manipulate and display data through constructs such as for-each, apply-templates, choose/when etc. However this does not always cover all possible requirements of a transform. Sometimes there is a need to run code, and this is often performed in the following way:

<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl cargowire" xmlns:ms="urn:schemas-microsoft-com:xslt" xmlns:cargowire="http://cargowire.net/XSL"> <ms:script language="C#" implements-prefix="cargowire"> <![CDATA[ public string MakePointlessStatement() { // This could actually be done without code but what the hey... return "Hello World!"; } ]]> </ms:script> <xsl:template match="/"> <xsl:value-of select="cargowire:MakePointlessStatement()" /> </xsl:template> </xsl:stylesheet>

The problem is that this not only looks and feels messy but mixes C# code (incidently this can be a number of languages… javascript and vb for example) with XSL files leading to a loss of intellisense in Visual Studio, less ease of deploying with your usual common code libraries and less ease of integration with your existing classes.

So what's the better way?

Extension Objects

Luckily for us (and with a quick look at the first intellisense item on an XsltArgumentList instance) .net enables us to pass in an object instance…

First we need a class that might be useful to have inside an XSL document.

using System; using System.Web; namespace ExtensionObjects { public class XslWebPage { public string GetExtensionlessAbsolutePath() { int length = HttpContext.Current.Request.Url.AbsolutePath.LastIndexOf('.'); return HttpContext.Current.Request.Url.AbsolutePath.Substring(0, (length > -1) ? length : HttpContext.Current.Request.Url.AbsolutePath.Length); } } }

Ok, so you may find little use for such a class but it's used on this site as part of the URL creation within XSL generated pages. It's intended to act as a wrapper for the usual 'Page' object to enable any request type operations.

Lets pretend we have an <asp:Xml ID="myXML" runat="server" /> control in the markup of a page and a pre-populated XmlDocument instance called xDoc. The following code would create a new XsltArgumentList before adding an XslWebPage instance and binding the translated XML to the control.

myXML.XPathNavigator = xDoc.CreateNavigator(); System.Xml.Xsl.XsltArgumentList xtal = new System.Xml.Xsl.XsltArgumentList(); xtal.AddExtensionObject("urn:XslWebPage", new XslWebPage()); myXML.TransformSource = Server.MapPath("/transform.xsl"); myXML.TransformArgumentList = xtal; myXML.DataBind();

To use this object within your transform is simple. First you must register the namespace to match what was specified when the object was added to the argument list.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl cargowire page" xmlns:ms="urn:schemas-microsoft-com:xslt" xmlns:cargowire="urn:http://cargowire.net/XSL" xmlns:page="urn:XslWebPage">

Then it can be used whenever needed:

<xsl:value-of select="page:GetExtensionlessAbsolutePath()" />

Simple as that.

Conclusion

This is quite a simple addition to your XML/XSL armoury but one that I've found to be incredibly helpful particularly in avoiding an abundance of Xsl Parameters being passed here there and everywhere for things like URLs.

The plus side is that your XSL functions can be grouped into your common code libraries under a shared namespace (or even in one huge xsl utility if you want to go there!). You may even wish to go further and create a subclass of XslTransform overriding transform() to always submit your required utility classes as extension objects. This could have the added bonus of saving the hassle of maintaining xsl includes of functions files.

]]>
3D Knowledge Representation [Dissertation] http://cargowire.net/articles/threedimensionalknowledgerepresentation http://cargowire.net/articles/threedimensionalknowledgerepresentation Craig Thu, 29 Sep 2005 09:00:00 GMT An investigation into, and prototyping of, a multimedia solution to the representation of a field of study. This report details and discusses the creation and proof of concept of a multimedia 3Dimensional knowledge map driven application for the representation of the concepts within a field of study.

The example field of study is that of ‘Information Systems’. The report discusses the issues surrounding such a representation, moving onto possible solutions, concluding with the creation and discussion of the implementation of a 3Dimensional interactive multimedia artefact.

To begin, the variety of investigations into learning and the benefits of multimedia are briefly presented. This is followed by a discussion of the problem area connecting the two areas of marketing and learning in the context of higher education course information. A focus on and analysis of mind mapping, concept mapping and interactivity is made and followed by a competitor analysis before a user interface design and discussion of the many issues surrounding a 3D interface. The choice of development tool and the final outcome is then evaluated for its effectiveness in meeting the problem. Concluding points are drawn on the basis of the current application and the scope for future development.

[Information Systems Dissertation Project: Abstract Only]

]]>