For the last 2 days I’ve been attending the Software Architect 2009 conference located at the iconic Royal College of Physicians building opposite Regent's Park in central London. Overall the events have been interesting, that said, the content has not in general been particularly new or ground breaking, but that is probably the nature of the discipline. It has however been good to be reminded of key principles, to listen to the views of others, and as always I’ve found it quite thought provoking. For each talk I attended I’ve created an entry on Twitter @ptrelford:
Tim Ewald on Saving Software Architecture: "When you go too far up, abstraction-wise, you run out of oxygen" Joel on Architecture Astronauts
Kevin Seal on MorganDirect's client-side architecture: Swing app with Eclipse IDE look, blackboard pattern, detailed logs & takes screenshots
Kevlin Henney on Slicing design over time: take time estimate & half it, coding is performance art so practice, test cases are propositions.
Dave Wheeler on Coding a solid UI: "WPF is great", dependency properties are cool, do MVVM pattern, get an HCI expert & use Expression Blend
Richard Blewett on What's New in WF 4.0: Everything. Complete API rewrite. 3.5 favoured code based workflow. 4.0 declarative XAML is king.
Dino Esposito asks "How good are you at .NET software design?" Separation of concerns, OOD principles - prefer composition to inheritance etc
Kevlin Henney on Modelling in the age of agility: Most important aspect of modelling is the -ing, i.e. the social and collaborative aspects.
Simon Brown on "Documenting your software architecture - why and how?" Start with a context and set the scene. Put yourself in others shoes.
Most popular analogy: Construction (Tim Ewald & Kevlin Henney)
Favourite example: Fast-Track Construction of the Empire State Building (Kevlin Henney)
Best term usage: idempotent (Simon Brown)
Best vocabularly usage: pontificate (Kevlin Henney)
Only search term suggestion: Death by UML Fever (Kevlin Henney again)
The .Net Framework ships with a C# code compiler that lets you generate in-memory assemblies. This can be used to run C# scripts without the need for the installation of a large application like PowerShell. The following code, which targets .Net 2.0, builds into a 7K executable, and is all that is needed to run C# source files from the command line:
using System;
using System.CodeDom.Compiler;
using System.Collections.Specialized;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;
using Microsoft.CSharp;
using System.Collections.Generic;
static class Program
{
/// <summary>
/// Executes specified C# script file
/// </summary>
/// <param name="args">Path of C# script file</param>
static void Main(string[] args)
{
// Check parameters
if (args.Length == 0)
{
Console.WriteLine("Please specify a C# script file");
Environment.Exit(-1);
}
// First parameter is source file path
string path = args[0];
// Check file exists
if (!File.Exists(path))
{
Console.WriteLine("Specified file does not exist");
Environment.Exit(-1);
}
// Read source from file
string source = ReadFile(path);
// Initialize compiler options
CompilerParameters compilerParameters =
new CompilerParameters();
compilerParameters.GenerateExecutable = true;
compilerParameters.GenerateInMemory = true;
compilerParameters.TreatWarningsAsErrors = true;
compilerParameters.CompilerOptions = "/nowarn:1633"; // unrecognized pragmas
// Prepass source for #pragma reference statements
StringReader reader = new StringReader(source);
while (true)
{
string line = reader.ReadLine();
if (line == null) break;
string pattern =
"\\s*#pragma\\s+reference\\s+\"(?<path>[^\"]*)\"\\s*";
Match match = Regex.Match(line, pattern);
if (match.Success)
compilerParameters.ReferencedAssemblies.Add
(match.Groups["path"].Value);
}
// Specify .NET version
Dictionary<string, string> providerOptions =
new Dictionary<string, string>();
providerOptions.Add("CompilerVersion", "v3.5");
CSharpCodeProvider provider = new CSharpCodeProvider(providerOptions);
// Compile source
CompilerResults results =
provider.CompileAssemblyFromSource(
compilerParameters,
new string[] { source });
// Show errors
if (results.Errors.HasErrors)
{
Console.WriteLine("Errors Building " + path);
foreach (var err in results.Errors)
Console.WriteLine(err);
Environment.Exit(-1);
}
// Extract argument tail
string[] parameters = new string[args.Length - 1];
Array.Copy(args, 1, parameters, 0, args.Length-1);
// Invoke compiled assembly's entry point
results.CompiledAssembly.EntryPoint.Invoke
(null, new object[1] { parameters });
}
private static string ReadFile(string path)
{
using (StreamReader reader = File.OpenText(path))
return reader.ReadToEnd();
}
}
Script files look just like Console applications:
using System;
public class Class1
{
static void Main(string[] args)
{
Console.WriteLine("Hello World");
}
}
Finally additional assemblies can be referenced using #pragma directives:
#pragma warning disable 1633 // disable unrecognized pragma directive warning
#pragma reference "System.Windows.Forms.dll"
using System.Windows.Forms;
public class Class1
{
static void Main(string[] args)
{
MessageBox.Show("Hello World");
}
}
The Open Source eXchange III was a mini-conference where members of the ALT.NET community talked about their favourite alternative .NET tools that increase programmer productivity. Units of Measure is a cool language feature in F#, developed by Andrew Kennedy, that lets you easily annotate values with units like metres, kilograms or seconds. Then F# type inference kicks in to give you automatic checking of your unit types at design and compile time, but cost you nothing at run time, e.g.
let gravityOnEarth = 9.8f<m/s^2> // Acceleration
Following a bit of a Apollo 40th Anniversary theme, I presented 3 code samples (attached):
-
Statistics
-
Orbital Mechanics
-
Lunar Lander
Resources:
Further reading: