Prairie Developer Conference

Prairie Dev Con was a blast. Great job by D’Arcy on organizing the conference. Thank you to everyone who attended my sessions and especially those who asked questions. I also enjoyed catching up with many of my friends who showed up, even if I was only able to speak to some of the briefly. (It was a busy two days.)

For those of you looking for session slides and code, you can find it here:

jQuery Dojo

NHibernate Dojo

Advanced NHibernate

BTW – I applaud D’Arcy’s bravery in going to a Saskatchewan Roughriders autograph signing in an Alouette jersey and asking them to sign his calculator. Classic! For those of you unfamiliar with the story, the Alouettes beat the Roughriders in the Grey Cup (Canadian football equivalent of the SuperBowl) this year due to a “too many men on the field” penalty in the closing seconds of the game. Fortunately the Roughriders were good sports about the prank. Check out D’Arcy’s blog post for full details and video footage of the stunt.

psake It is with great pleasure that I announce psake v4.00, which you can download here. The project has grown up a great deal in the last few months. More projects are using psake for orchestrating their builds and we have more developers submitting patches. I’m really pleased with how psake is growing up. GitHub has become our coordination point for the project, which you can find here, and we will be retiring the Google Code site. Jorge has started work on a FAQ, which will make it easier for developers to get started with psake. Look for it on the GitHub wiki in the next few weeks.

What’s new in psake v4.00?

  • Exec helper function
  • .NET 4.0 support
  • 64-bit support
  • psake.ps1 helper script
  • Support for parameters & properties
  • Support for nested builds
  • Tab expansion
  • Invoke default script
  • Various minor bug fixes

Exec Helper Function

The exec helper function was included in the psake v2.02 patch, but it bears mentioning again. If you are executing a command line program (such as msbuild.exe, aspnet_compiler.exe, pskill.exe, …) rather than a PowerShell function, it will not throw an execption on failure, but return a non-zero error code. We added the exec helper function, which takes care of checking the error code and throwing an exception for command line executables.

task Compile -depends Clean {
  exec { msbuild Foo.sln }
}

You can find out more details here.

.NET 4.0 Support

psake still defaults to .NET Framework 3.5, but you can specify another framework to use from the command line:


invoke-psake examples\default.ps1 -framework 4.0

Or from within your script:

$framework = '4.0'

task default -depends MsBuild

task MsBuild {
  exec { msbuild /version }
}

64-bit Support

You can now specify whether you want to use 32-bit (x86) or 64-bit (x64) tools when building your projects.

invoke-psake examples\default.ps1 -framework 3.5x86
invoke-psake examples\default.ps1 -framework 3.5x64

If you don’t specify x86 or x64 after the framework version, psake selects the framework bitness based on whether you’re running from a 32-bit or 64-bit PowerShell prompt. (On 64-bit Windows, the default PowerShell prompt is 64-bit. If you want a 32-bit prompt, launch “Windows PowerShell (x86)”. Valid values for the framework are ’1.0′, ’1.1′, ’2.0′, ’2.0×86′, ’2.0×64′, ’3.0′, ’3.0×86′, ’3.0×64′, ’3.5′, ’3.5×86′, ’3.5×64′, ’4.0′, ’4.0×86′, and ’4.0×64′.

psake.ps1 Helper Script

Because psake is a PowerShell module, you have to import the module before using it.

import-module .\psake.psm1
invoke-psake examples\default.ps1
# do some work
invoke-psake examples\default.ps1
# do some more work
remove-module psake # when done, remove psake or close your PS prompt

If you want to use the psake.psm1 stored in a particular project’s repository, you have to remember to import the correct version of psake from that project. You also need to create a ps1, bat, or cmd file for your continuous integration server so that the correct version of psake is registered to orchestrate the build. We have standardized this using a psake.ps1 helper script:

# psake.ps1
# Helper script for those who want to run
# psake without importing the module.
import-module .\psake.psm1
invoke-psake @args
remove-module psake

With this script, you can now execute psake without first importing the module.

.\psake examples\default.ps1 test

You can read about the splatting operator (@) here if you’re wondering what invoke-psake @args does.

Support for Parameters and Properties

Invoke-psake has two new options, –parameters and –properties. Parameters is a hashtable passed into the current build script. These parameters are processed before any ‘Properties’ functions in your build scripts, which means you can use them from within your Properties.

invoke-psake Deploy.ps1 -parameters @{server=’Server01’}

# Deploy.ps1
properties {
  $serverToDeployTo = $server
}

task default -depends All

# additional tasks

Parameters are great when you have required information. Properties on the other hand are used to override default values.

invoke-psake Build.ps1 -properties @{config='Release'}

# Build.ps1
properties {
  $config = 'Debug'
}

task default -depends All

# additional tasks

Support for Nested Builds

You can now invoke build scripts from within other build scripts. This allows you to break large, complex scripts into smaller, more manageable ones.

task default -depends RunNested1, RunNested2

task RunNested1 {
  Invoke-psake .\nested\nested1.ps1
}

task RunNested2 {
  Invoke-psake .\nested\nested2.ps1
}

Tab Expansion

Dusty Candland implemented PowerShell tab expansion for psake. You can find instructions on setting up tab expansion in ./tabexpansion/Readme.PsakeTab.txt in the download. Once configured, you can:

tab completion for file name: psake d<tab> -> psake .\default.ps1
tab completion for parameters: psake -t<tab> -> psake -task
tab completion for tasks: psake -task c<tab> -> psake -task Clean

You can find more details on Dusty’s blog here. Excellent addition! Thanks, Dusty.

Invoke Default Script

Jason Jarrett provided this welcome fix, which allows you to execute tasks without specifying the default build file name (default.ps1).

invoke-psake Compile # Executes the Compile task in default.ps1

Previously you had to specify invoke-psake default.ps1 Compile. You could only omit default.ps1 if you were running the default task.

Big Thanks!

Thanks to everyone who contributed to this release, especially Jorge Matos who contributed many of the new features noted above. If you have any questions, please join the psake-users Google Group. If you’re interested in contributing to the ongoing development, we also have a psake-dev Google Group. Happy scripting, everyone!

P.S. Wondering what happened to psake v3.00? It’s chilling with its friends EF v2 and EF v3…

BatmanNo, this post is not a tribute to the fabulously kitschy Batman TV series (1966-1968) starring Adam West and Burt Ward. Or a tribute to the onomatopoeic sounds for which it and the Batman comics were famous. This show did however come to mind when I was trying to solve a PowerShell problem and ran across the wonderfully-named splatting (@) operator introduced in PowerShell v2. Before we get to the splatting operator, let’s look at the problem that it was designed to solve.

With psake v2 came the change from a PowerShell script to a PowerShell module. Modules provide a lot of advantages over a simple script. For psake the compelling advantages were better control over scoping and better integration with PowerShell’s help system. One disadvantage was that you now had to first import the module before you could use psake.

image

ASIDE: If you’re wondering about the “James@EDDINGS psake [master +0 ~1 -0]>” stuff, I’ve installed Mark Embling’s awesome PowerShell Git Prompt, which is simply a custom PowerShell prompt. It tells me that my user is James, I’m logged into my main dev machine (EDDINGS), I’m in the psake directory (c:\dev\oss\psake) – though I only display the last part of the path for brevity, I’m on the “master” branch, I have no pending additions (+0), no pending changes (~0), and no pending deletions (-0). (I need to see if I can hack in how many commits forward or back I am from a tracked remote.) Everything in brackets is omitted if it isn’t a Git directory. Another good set of Git/PowerShell scripts is Jeremy Skinner’s PowerShell Git Tab Expansion for completing common command names, branch names, and remote names. If you are using Git and PowerShell, I would highly recommend both Mark’s and Jeremy’s scripts. If you don’t want to copy/paste them together, you can grab them from my random collection of PowerShell scripts here.

Note how we had to first call “import-module” before we could use psake. For some people, they install the latest version of psake in some well-known location, import the module, and then run it from there until the next update comes out. For others (e.g. me), we like to version psake along with our source code and other dependencies. Importing a project-specific copy of psake becomes a headache very quickly. So I wrote a little shim script to register psake, run it, and then unregister it.

# Helper script for those who want to run
# psake without importing the module.
import-module .\psake.psm1
invoke-psake $args
remove-module psake

Seems reasonable enough. We simply pass along the script arguments ($args) to the invoke-psake command and everything should be fine.

image

OK. What happened? PowerShell did what we told it to. It called the function, invoke-psake, with an array as its first parameter rather than using the array as the list of parameters as we intended. Let’s fix that.

# Helper script for those who want to run
# psake without importing the module.
import-module .\psake.psm1
invoke-psake $args[0] $args[1]
remove-module psake

One little problem.

image

Note that we left out the task (“clean” previously) so that psake would use the default. Rather than using the default, invoke-psake has been passed a null argument for the task. We could fix this by detecting null arguments in invoke-psake and explicitly specifying the defaults. It’s ugly because we couldn’t use PowerShell’s syntax for specifying defaults, but it would work. Another problem is that we would need to add as many $args[N] as we expected to receive arguments. A messy solution all around.

Fortunately PowerShell v2 has an elegant solution to this problem called the splatting operator, denoted by @. The splatting operator binds an array to the argument list of a function.

# Helper script for those who want to run
# psake without importing the module.
import-module .\psake.psm1
invoke-psake @args
remove-module psake

Note the subtle change. Rather than using $args we use @args.

image

Success! And it’s not just for passing arguments from one script to another. You can create arr

 image

Note the call to “Add $addends” where PowerShell called the Add function once for every item in the array. Not what we intended. “Add @addends” using the splatting operator gave us the expected result. You can even use a hashtable to splat named parameters.

image

Note that the answer was 1 (e.g. 11 % 10) and not 10 (e.g. 10 % 11). The splatting operator properly bound the value 11 to the x parameter and 10 to the y parameter, just as it was in the hashtable.

The splatting operator provides us with a tremendous amount of flexibility in manipulating function and script arguments. It’s a useful tool to add to your PowerShell arsenal. Go forth and SPLAT!

DevTeach.com Another year, another DevTeach. A big thank you to everyone involved. To the organizers, Jean-Rene Roy and Maryse Dubois, thank you for continuing to support and encourage the Canadian developer community. To my fellow Tech Chairs, for helping select an awesome array of both local and international talent to present. To my fellow speakers, for giving some fantastic talks. To all the attendees, for their eager participation, helpful comments, and continued encouragement. To old friends and new whom I spent catching up with in the unofficial speakers lounge, at dinner, and around drinks. There is always something new and fun at DevTeach and this year was no exception. Here are the slides decks and code for those interested:

Convention-over-Configuration in a Web World (pptx | code)

Convention-over-Configuration in an Agile World (pptx | code)

Agile Development with IoC and ORM (pptx | code)

If anyone has any questions, comments, or issues with the slidedecks or code, don’t hestitate to leave me a comment.

Prairie Developer ConferenceA few months ago, my friend, D’Arcy Lussier, and I had the following conversation:

D’Arcy:
Want to speak at a developer conference?
Me:
Sure. Sounds awesome!
D’Arcy:
It’ll be in Regina, Saskatchewan.
Me:
Sweet!
D’Arcy:
It’ll be in June.
Me:
Where do I sign up!?!

All joking aside, D’Arcy is putting together what looks to be a great regional conference. I think D’Arcy’s explanation of how this conference came to be describes it best:

“Having lived my life between Manitoba and Saskatchewan, I saw an opportunity to create an event to bring high calibre presenters and sessions to the talented technology professionals of the Canadian prairies, and thus the Prairie Developer Conference was born!”
– D’Arcy Lussier, Prairie Developer Conference Chair

The conference will take place June 2 & 3, 2010 in Regina, Saskatchewan. I’ll be giving two dojos, one on jQuery and the other on NHibernate. If you’ve been wanting to learn these technologies, I’ll be walking you through them – dojo-style – so you can follow along with your own laptops.

NHibernateNHibernate Dojo

I’ll be covering NHibernate fundamentals, mapping with Fluent NHibernate, and querying with LINQ to NHibernate. This session is intended to be very interactive with attendees working examples on their own laptops and asking questions.

jQueryjQuery Dojo

I should have called this session: Dr. Weblove or How I Learned to Stop Worrying and Love JavaScript. In this dojo, I’ll take you on a tour of jQuery and show you that JavaScript is anything but a toy language. JavaScript is a powerful functional language and jQuery allows you to harness that power with truly amazing results. Come learn about selectors, effects, DOM manipulation, CSS, AJAX, eventing, and much more.

imageIn addition to my two dojos and sessions by many other speakers, my friend, Donald “IglooCoder” Belcham will be giving a post-con on “Making the Most of Brownfield Application Development”. If you’ve got a legacy codebase that needs taming – and who doesn’t? – this is a great post-con to check out.

Registration is now open at a price that won’t break your (or your employer’s) bank. Come check it out.

I must admit that I don’t much care for PowerShell’s default behaviour with respect to errors, which is to continue on error. It feels very VB6 “On Error Resume Next”-ish. Given that it is a shell scripting language, I can understand why the PowerShell team chose this as a default. Fortunately you can change the default by setting $ErrorActionPreference = ‘Stop’, which terminates execution by throwing an exception. (The default value is Continue, which means the script prints the error and continues executing.) Unfortunately this only works for PowerShell commands and not external executables that return non-zero error codes. (In the shell world, a return code of zero (0) indicates success and anything else indicates failure.)

Take the following simple script:

'Starting script...'
$ErrorActionPreference = 'Stop'
ping -badoption
"Last Exit Code was: $LastExitCode"
rm nonexistent.txt
'Finished script'

image

Notice how execution continued after the ping command failed with an exit code of one (1) even though we have $ErrorActionPreference set to ‘Stop’. Also notice that the rm command, which is an alias for the PowerShell command, Remove-Item, did cause execution to abort as expected and ‘Finished script’ was never printed to the console. The discrepancy in error handling between PowerShell commands and executables is annoying and forces us to constantly think about what we’re calling – a PowerShell command or an executable. The obvious solution is:

'Starting script...'
$ErrorActionPreference = 'Stop'
ping -badoption
if ($LastExitCode -ne 0) { throw 'An error has occurred...' }
rm nonexistent.txt
'Finished script'

image

The error handling code adds a lot of noise, IMHO, and feels like a throwback to COM and HRESULTs. Can we do better? Jorge Matos, one of the psake contributors came up with this elegant helper function:

function Exec([scriptblock]$cmd, [string]$errorMessage = "Error executing command: " + $cmd) {
  & $cmd
  if ($LastExitCode -ne 0) {
    throw $errorMessage
  }
}

Note the “& $cmd” syntax. $cmd is a scriptblock and & is used to execute the scriptblock. We can now re-write our original script as follows. (N.B. Exec function is elided for brevity.)

'Starting script...'
$ErrorActionPreference = 'Stop'
exec { ping -badoption }
rm nonexistent.txt
'Finished script'

image

The script now terminates when the bad ping command is executed. We do have to remember to surround executables with exec {}, but this is less noise IMHO than having to check $LastExitCode and throwing an exception.

For those of you using psake for your builds, the Exec helper function is included in the latest versions of the psake module. So you can use it in your build tasks to ensure that you don’t try to run unit tests if msbuild fails horribly. smile

Happy Scripting!

DevTeachDevTeach is heading back to Toronto in a few weeks (March 8-12, 2010)and you’ll get a bigger dose of awesome than ever before. We’ve got a fantastic line-up of top-notch, internationally renowned speakers. 6 tracks covering Agile, Web, Windows, Silverlight, Architecture, and SharePoint. A metric ton of sessions. (I’m both the Agile and Web Track Chairs and am really excited about the speakers and sessions for each.)

ee402630.VisualStudio_lgMicrosoft Canada is a platinum sponsor and every attendee receives a full copy of Visual Studio Professional with MSDN Premium. (N.B. Conference registration costs less than this subscription alone!)

imageAnd if you can’t get enough of that Sugar Crisp James Kovacs,  I’ll be there in full force with two sessions and a one-day post-con on agile development.

Convention-over-Configuration in an Agile World

As developers, we spend an inordinate amount of time writing “glue code”. We write code to transform database rows to domain objects… domain objects to view-models or DTOs… We write code to configure inversion of control containers and wire dependencies together. We write code to style our UIs and respond to UI events. Wouldn’t it be nice if this could happen automagically for us? This session will look at using convention-based approaches using Fluent NHibernate and Castle Windsor to reduce the amount of repetitive code and accelerate application development.

Convention-over-Configuration in a Web World

As developers, we spend an inordinate amount of time writing “glue code”. We write code to transform database rows to domain objects… domain objects to view-models or DTOs… We write code to configure inversion of control containers and wire dependencies together. We write code to style our UIs and respond to UI events. Wouldn’t it be nice if this could happen automagically for us? This session will look at using convention-based approaches using AutoMapper and jQuery to reduce the amount of repetitive code and accelerate application development.

Agile Development with IoC and ORM (Post-Con)

As developers we now have powerful tools in our toolbox, such inversion of control containers and object-relational mappers. But how can we use these tools to rapidly build maintainable and flexible applications? In this pre-con, we will look at advanced techniques such as convention-over-configuration in IoC containers and automapping ORMs to quickly build applications that can evolve over time. We will use test-driven development (TDD) to design and evolve a complete working application with supporting infrastructure during this one-day workshop.

Hope to see you in Toronto!

image

A few announcements… First the big one. Many people have been using psake – both the PowerShell 1.0- and 2.0-compatible versions – in production without any significant issues. For that reason, we have released psake v1.00 (compatible with PowerShell 1.0). The only difference between psake v1.00 and psake v0.23 is the version number. My friend, Ayende, has a great example of converting Rhino Mocks build to use psake.

http://psake.googlecode.com/files/psake-v1.00.zip

We have released psake v2.01 (compatible with PowerShell 2.0). (This was formerly called psake v0.24, “Jorge”, and psake-ps2.) A big thanks to Jorge Matos for all his work on psake v2.01.

http://psake.googlecode.com/files/psake-v2.01.zip

A few minor changes… The source code for psake has been moved to GitHub and the SVN repository at Google Code has been retired. We will still be using Google Code for bug tracking, wiki pages, etc. If you want the latest source code, you can always download a zip file for master (aka trunk in SVN terms) – or any tags/branches – from:

http://github.com/JamesKovacs/psake

Note that there is no need to install Git to download the latest package as GitHub will create the appropriate zip file on the fly.

If you have some great idea, you can download the git repo from git://github.com/JamesKovacs/psake.git or http://github.com/JamesKovacs/psake.git. (msysgit is the Git package of choice for Windows. You can download it from http://code.google.com/p/msysgit/.) I would encourage you to read Jeremy Skinner’s excellent guide for contributing to MvcContrib via GitHub. Just mentally replace “MvcContrib” with “psake”, though I’d encourage you to contribute to MvcContrib too. :)

I would like to offer lots of kudos to my collaborators/conspirators on the project. Jorge Matos has been instrumental in updating/improving psake to use the new PowerShell v2 features. Thanks to Shaun Becker for patches and answering newsgroup questions. And thanks to Eric Hexter for his assistance in moderating the psake-users Google Group. I am heartened and thankful for the willing collaboration on this project and am excited to watch it grow. If you have any questions, please do not hesitate to ask.

Going forward, we are retiring psake v1.00 and focusing on psake v2.00. If there is demand for a PowerShell v1-compatible version of psake, we will create a branch based on the v1.00 tag, but we will mostly be focused on the PowerShell v2-compatible version (aka psake v2.00). So your next question probably is…

What’s New in psake v2.01?

(from Jorge Matos)

The main difference is that psake v2.01 has been re-written as a module that contains advanced functions.  Someone using the module could either run the import-module command with the path to the module file (i.e. import-module .\psake.psm1) or (my preference) you can copy the psake.psm1 into a folder called psake into the “Modules” folder in your profile directory (you may have to create it if it’s not there) or your machine-wide “Modules” directory:

i.e. Profile Directory:

C:\Users\Jorge\Documents\WindowsPowerShell\Modules\psake

i.e. Machine-wide Modules folder:

C:\Windows\System32\WindowsPowerShell\v1.0\Modules\psake

Once the psake folder is created and you’ve copied the psake.psm1 file into it – restart PS and type “import-module psake” – PS will find the module and load it automatically.  What I’ve done is add the “Import-Module psake” to my profile script so that it is loaded everytime I startup PS.

Module Benefits:
  1. Build scripts don’t need to know where psake is installed, they just call Invoke-psake and it works.
  2. Encapsulation… Global variables are no longer required since they can be private to a module unless explicitly exported (I haven’t gotten around to actually changing the psake code to not use global variables yet).
  3. Modules can be unloaded if needed which removes all the code and variables from memory.
Advanced Functions:

The other big difference is that the “Invoke-psake” and “Task” functions have been converted into Advanced Functions which basically means you can take advantage of comment help which means you can type help invoke-psake and you will get back real help with examples.

Minor changes:
  1. Coding style is different.
  2. Try/Catch is used instead of the “Trap” statement.
  3. Got rid of the “exec” function.
  4. You can now define “Pre” and “Post” actions for a task.
  5. You can define how the task name will be formatted.
  6. You can define a “TaskSetup” function that will be executed before every task (took that from NUnit).
  7. You can define a “TaskTearDown” function that will be executed after every task (took that from NUnit too).
  8. Create a global variable called “psake_buildSucceeded” that will be set to true if the build succeeds – scripts can check this.
  9. Also added a “$noexit” switch to Run-Psake so that the function will not use the exit() function so that you can test a build script at the command line without PS closing down (the default behavior when the build fails is to call exit(1) so that the calling code can determine if the build failed or not).
  10. The psake-buildTester.ps1 had to be changed slightly in order for it to call the Invoke-psake function.
  11. Added more examples in the .\examples folder for POST conditions, PRE and POST Actions, etc.

Happy (build) scripting!

As many of you know, I am an independent consultant and use my own laptop when possible. I’ve got all my tools set up the way I like them and everything else that I need to be productive. Given that I work for multiple clients, I can’t join my laptop to any particular client’s domain. First is the hassle factor, especially when switching between different clients within a week. Each domain join requires a domain admin to authorize the join by typing in his/her credentials when prompted on my laptop. Second I don’t want a client’s Group Policy being applied to my laptop. Third – and more importantly – is the non-disclosure agreements that I sign with clients. If I join my laptop to a domain, the domain admins have full rights to my machine and hence data from other clients. So domain joining just isn’t an option.

In most cases, not being joined to a client’s domain doesn’t make one iota of difference. You need to access a network share or printer, browser to it and you will be prompted for domain credentials. The fact that you’re using different domain credentials to access the resource from those that you logged in with doesn’t matter one bit. If you want to expedite the process and not wait for an authentication time-out, you can utilize NET USE from the command line to tell Windows which credentials you want to use when accessing certain computers. You can even make them persistent or roll the whole thing into a batch script that you can execute whenever at a particular client.

net use \\server /user:domain\username /persistent:yes

Unfortunately this doesn’t work in all cases. One of my longstanding development pet peeves has been certain tools – I’m looking at you SQL Server Management Studio and SQL Query Analyzer – that don’t allow you to specify alternate domain credentials for authentication. For example, SQL Server Management Studio allows you to log into a SQL Server instance using Windows Authentication or SQL Server Authentication. If the SQL instance requires Windows Authentication – the recommended configuration – SQL Server Management Studio uses your logged in credentials. This works well if your computer is part of the domain, but fails horribly if not. It doesn’t let you specify alternate credentials or even prompt you for alternate credentials if the log-in fails.

I’ve tried seemingly everything. NET USE doesn’t help here because NET USE is specifically for network shares.

net use \\sql-server-name /user:domain\username # DOES NOT WORK – Only provides the domain credentials when accessing shares

RUNAS also fails – either the SHIFT right-click variety or command line – as it tries to run the command locally as the domain user, who is unknown by your computer because you’re not part of the domain.

runas /user:domain\username “C:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn\VSShell\Common7\IDE\Ssms.exe”

 image

For years (yes, years) I have resorted to using Remote Desktop to log into a domain computer so that I could run SQL Server Management Studio, used a domain-joined virtual machine, or begged co-workers to run commands for me. Now I feel foolish because I stumbled upon a solution that has been built into Windows for years. It is a simple command line switch for the RUNAS command that I never noticed: /netonly. (Note that the /netonly flag is not accessible via the SHIFT right-click menu, only via the command line.)

runas /netonly /user:domain\username “C:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn\VSShell\Common7\IDE\Ssms.exe”

image

Success! And SQL Server Management Studio running using /netonly domain credentials. The command is run as my local user, but uses the supplied domain credentials only when accessing the network.

image

image

I can access remote SQL Servers using Windows Authentication without problem now! (You’ll have to take my word for it or try it yourself as it would be impolite for me to show screenshots of me accessing a client’s SQL Server.) Hopefully this makes some other consultant’s life a little bit easier.

Darth VaderThe Edmonton Code Camp was a lot of fun. It was wonderful to catch up with friends – old and new – over lunch and dinner. Thanks to Dave Woods for inviting me.

I have been enjoying sharing my ideas about convention-over-configuration and how it can simplify software development. You expend some serious brain power over figuring out how to enable your application-specific conventions, but everything after that flows easily and without repetition. You end up doing more with less code. During the talk, I demonstrated how frameworks like Fluent NHibernate, AutoMapper, Castle Windsor, ASP.NET MVC, and jQuery support this style of development. (Links below.) I only scratched the surface though. Other frameworks like StructureMap and FubuMVC also are heavily convention-based. With a bit of creative thinking, you can use these techniques in your own code to reduce duplication and increase flexibility.

For those of you who attended, you’ll realize why Darth Vader accompanies this post. For everyone else, you’ll have to check out the slidedeck and code:

PPTX | Code