random .NET and web development musings

You use a convention!

public class StringPropertyConvention : IPropertyConvention, IPropertyConventionAcceptance
{
	public void Apply(IPropertyInstance instance)
	{
		instance.Length(4001);
	}

	public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria)
	{
		criteria.Expect(x => x.Property.PropertyType == typeof (string));
	}
}

:D

Make sure you register the conventions with the automapper.

Peace

If you need to get access to the date part of a DateTime through HQL, the easiest way is to use a custom dialect:

public class CustomDialect : SQLiteDialect
{
	public CustomDialect()
	{
		RegisterFunction("DateOnly", new StandardSQLFunction("date", NHibernateUtil.String));
	}
}

public class CustomDialect : MsSql2005Dialect
{
	public CustomDialect()
	{
		RegisterFunction("DateOnly", new SQLFunctionTemplate(NHibernateUtil.DateTime, "DATEADD(dd, 0, DATEDIFF(dd, 0, ?1))"));
	}
}

Because I use SQLite for my integration tests and MSSQL2005 for my runtime database, I need two different dialects, one for each provider. Using the custom function name “DateOnly” I can have the same HQL work on both databases :D

You can then use this function, like so:

select DateOnly(x.Date), count(x.Id)
from someEntity x
group by DateOnly(x.Date)

Win.

Time and time again I encounter repositories which are just a free-for-all mess, so here is a definitive guide to SVN and project code organisation for the tidy-inept.

Most people will use their repository for multiple projects. For this reason it is a sensible idea to have top level folders which semantically group your code. How you do this depends largely on what code/projects you have in SVN. Here’s an example:

root
- Customer A
-- Project X
-- Project Y
- Customer B
-- Project Q
-- Project X

Next, under each Project you should have:

Project X
- trunk
- branches
- releases
- tags

Sometimes its more appropriate to have the releases folder under branches (as they technically are branches), it doesn’t really matter. What is important is that you are branching your releases!

.NET Project Organisation

Here is how I organise my projects:

/
/lib
/src
/src/<projectname>.sln
/src/<projectname><assembly-specific-names>
/tools
/rakefile.rb

Nice and clean :D

The lib folder holds all your 3rd party assemblies which your project utilises.
The src folder contains…you guessed it, your source code!
The tools folder contains mainly build tools and test runners. Mine also has the NHibernate Profiler in there, too.
The rakefile is my build script, if you enjoy angled-bracketed-unneccessaryness this could be your NAnt or MSBuild file.

Next, externals. If your project shares code with another, this shared code should be under a separate project, and included via an svn:external under the lib folder. For example:

/lib/<folder-for-external>

Useful Resources

Here are some great examples of best practices for code and svn organisation.

And here is an excellent book on the subject!

One tidy life….Done!

Following on from my recent post how to test asp.net mvc views existence, I found myself with in a very similar situation! This time however, it was FileResult instead of ViewResult.

I’m not making any excuses, this is far from the prettiest or most flexible solution, but for my setup it works perfectly :)

Have some code:

public abstract class ControllerTest<TController> where TController : IController
{
	protected void AssertFileIsCorrectAndExists(FileResult result, string filename)
	{
		// hack of death!!!!
		var webProjectPath = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, Path.Combine("../../../", typeof(TController).Assembly.GetName().Name)));

			// crudely trim leading ~/
		if (filename.StartsWith("~/"))
			filename = filename.Substring(2);

		var fullPath = Path.Combine(webProjectPath, filename);

		Assert.IsTrue(File.Exists(fullPath), "File `" + fullPath + "` does not exist");
	}

Following a recent embarrassing episode where I had been banging on about how unit testing saves the world, then released a broken site, I decided a solution to prevent this happening again was necessary!

I currently test my MVC ViewResults like this:

public class when_requesting_a_login_form : ControllerTest<LoginController>
{
	private ViewResult result;

	protected override void Act()
	{
		this.result = this.SubjectUnderTest.LogIn() as ViewResult;
	}

	[Test]
	public void the_login_view_should_be_returned()
	{
		this.result.ViewName.ShouldEqual("Login");
	}
}

However this doesn’t check that the Login.aspx view actually exists (which it didn’t in the case I’m talking about, as I only found out at runtime). Below is my new test:

[Test]
public void the_login_view_should_be_returned()
{
	AssertViewIsCorrectAndExists(result, "Login");
}

This assertion not only checks that the view names match, but also that the file exists on disc.

The solution is far from elegant, but it works, which is better than nothing!

Before I show you the codes, some prerequisite knowledge about my solution setup is required.

My folders are ALWAYS organised like this:

/src/Project.Web/
/src/Project.Domain/
/src/Project.Tests.Unit/

with these folder names matching the assembly names. This allows the following very fragile code to work:

protected void AssertViewIsCorrectAndExists(ViewResult result, string viewName)
{
	ViewEngines.Engines.Clear();
	ViewEngines.Engines.Add(new TestingViewEngine());
	Assert.AreEqual(viewName, result.ViewName, "View names do not match");

	var controllerContext = Stub<ControllerContext>();
	controllerContext.RouteData = new RouteData();
	controllerContext.Controller = SubjectUnderTest;

	var controllerName = typeof(TController).Name;
	controllerContext.RouteData.Values.Add("controller", controllerName.Substring(0, controllerName.Length - "controller".Length));

	var viewEngineResult = result.ViewEngineCollection.FindView(controllerContext, result.ViewName, result.MasterName);
	Assert.IsNotNull(viewEngineResult.View, "View '" + result.ViewName + "' could not be found");
}

public class TestingViewEngine : WebFormViewEngine
{
	public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
	{
		// hack of death!!!!
		var webProjectPath = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, Path.Combine("../../../", controllerContext.Controller.GetType().Assembly.GetName().Name)));

		foreach(var location in this.ViewLocationFormats)
		{
			var virtualViewPath = string.Format(location, viewName, controllerContext.RouteData.Values["controller"]);

			// crudely trim leading ~/
			virtualViewPath = virtualViewPath.Substring(2);

			var fullPath = Path.Combine(webProjectPath, virtualViewPath);

			if (File.Exists(fullPath))
				return new ViewEngineResult(MockRepository.GenerateStub<IView>(), this);
		}

		return new ViewEngineResult(this.ViewLocationFormats);
	}
}

Crude I know, but I hope this helps someone!

Following on from Robert Pickerings F# introduction at Progressive.Net in London last week, I was inspired to try and do something with this powerful functional language.

As an exercise I though’t I’d port some old code I wrote in Haskell several years ago, a simple Caeser Cipher cracker.

A Caeser Cipher works by shifting each letter of the alphabet by n positions. A shift of 3 would encode “ABCD” as “DEFG”. Due to this simple linear transform (y = x + c), the Caeser Cipher is incredibly easy to crack with frequency analysis. By shifting the ciphertext by 1-25 positions and comparing the frequency of each letter in the resulting plaintext candidate to a table of English letter frequencies, it is possible to easily discover the original plain text (assuming there is sufficient data to make the expected freqency distributions).

Here’s the code!

Disclaimer: This is the first F# code I’ve ever written, so don’t count on it being remotely decent. Suggestions for improvements are more than welcome!

#light

let alphabet = ['A'..'Z']

let getpos x xs = List.find_index ((=) x) xs

let let2nat c = getpos c alphabet

let nat2let i = alphabet.[i]

let shift i a =  nat2let ((let2nat a + i) % 26)

let encode i s = new string(Seq.map (fun c -> shift i c) s |> Seq.to_array)

let decode i = encode (26 - i)

let count c s = Seq.filter ((=) c) s |> Seq.length

let percent a b = (float a / float b) * 100.

let freqs ws = [for x in alphabet do
                   yield percent (count x ws) (Seq.length ws)]

let table          = [8.2; 1.5; 2.8; 4.3; 12.7; 2.2; 2.0; 6.1; 7.0;
                        0.2; 0.8; 4.0; 2.4; 6.7; 7.5; 1.9; 0.1; 6.0;
                        6.3; 9.1; 2.8; 1.0; 2.4; 0.2; 2.0; 0.1]

let chisqr os es =
    let chied = [for x, y in Seq.zip os es do
                       yield ((x - y) * (x - y)) / y]
    List.sum chied

let crack ws =
    let wws = [for x in [0..25] do
                   yield chisqr (freqs (decode x ws)) table]
    let n = getpos (Seq.min wws) wws
    decode n ws

let ciphertext = encode 5 "THEQUICKBROWNFOXJUMPEDOVERTHELAZYDOG"

let plaintext = crack ciphertext

System.Console.WriteLine(ciphertext)
System.Console.WriteLine(plaintext)

This produces:

YMJVZNHPGWTBSKTCOZRUJITAJWYMJQFEDITL
THEQUICKBROWNFOXJUMPEDOVERTHELAZYDOG

Ok this was an annoying one, If your TDD.Net runner keeps telling you “No tests run (No tests where found)” and you’ve run the “InstallTDNetRunner.bat” you can try the following:

Edit the InstallTDNetRunner.bat

and comment out the last 2 lines:

regedit MSpecTDNet.reg
del MSpecTDNet.reg

Run the bat file and a .reg should appear in the same folder. Edit this.

in there you should see: AssemblyPath”=”<some path>\\Machine.Specifications.TDNetRunner.dll”

Make sure this path is actually correct (it wasnt for me). Then save the .reg and run it.

Job done :)

Just a quick one, but it took me a while to figure this out. Hopefully this can help someone else out.

To get MSpec working with ReSharper you need to copy all the MSpec dlls into the resharper’s plugins folder, so you end up with:

ReSharper/bin/plugins/machine.specifications/<dlls here>

Make sure you delete whichever one of the ReSharperRunner dlls is not your ReSharper version!

Enjoy :)

Recently I posted about how you can split your CSS up into separate files, and use a NAnt task to combine them on build to aid development.

This can be very useful, but theres still room for improvement.

The YUI Compressor is a brilliant tool to remove whitespace and other bloat from your scripts which take up valuable bandwidth. Combining it with an automated build tool such as NAnt allows you to have all your scripts minified automatically on deployment.

Here are two example build tasks for minifying JavaScript and CSS respectively:

<target name="compress-js">
	<foreach item="File" property="filename">
		<in>
			<items basedir="output/build/assets/javascript/">
				<include name="/**/*.js" />
				<exclude name="/**/*.min.js" />
				<exclude name="/**/*.pack.js" />
			</items>
		</in>
		<do>
			<exec basedir="." program="${JavaPath}java" commandline=" -jar ${YUICompressorPath}yuicompressor-2.4.1.jar --type js --charset utf-8 -o &amp;quot;${filename}&amp;quot; &amp;quot;${filename}&amp;quot;" failonerror="true" />
		</do>
	</foreach>
</target>

<target name="compress-css" depends="combine-css">
	<foreach item="File" property="filename">
		<in>
			<items basedir="output/build/assets/css/">
				<include name="/**/*.css" />
				<exclude name="/**/*.min.css" />
				<exclude name="/**/*.pack.css" />
			</items>
		</in>
		<do>
			<exec basedir="." program="${JavaPath}java" commandline=" -jar ${YUICompressorPath}yuicompressor-2.4.1.jar --type css --charset utf-8 -o &amp;quot;${filename}&amp;quot; &amp;quot;${filename}&amp;quot;" failonerror="true" />
		</do>
	</foreach>
</target>

Using this in combination with my CssCombiner, I achieve an average of 70% compression!

Enoy :)

One of the most difficult aspecs of web development today is managing and maintaining your stylesheets. Typically you have a single huge file, divided into sections by comment blocks (if you’re organised). Navigating to the group of styles you need to edit typically involves Ctrl-F and lots of inside knowledge. Individual CSS developers tend to have their own quirks when it comes to the internal organisation of their “monolith.css”. Some like to separate structure and layout from colour and style whilst others like to define all attributes for a selector in a single place. The result of all these different, typically unmanaged techniques can make it very difficult for maintenence developers to get to grips with legacy stylesheets, surely there must be a solution?

Take a look at this CSS from a recent project I worked on…



css-organisation

default.css contains:

@Import url(Reset.css);
@Import url(MainLayout.css);
@Import url(Components/Header.css);
@Import url(Components/Misc.css);
@Import url(Components/WhiteBox.css);
@Import url(Components/Forms.css);
@Import url(Components/BaseModal.css);
@Import url(Components/CustomModal.css);
@Import url(Components/Popup.css);
@Import url(Components/DefinitionList.css);
@Import url(Components/ResultMessage.css);
@Import url(Components/ShipmentCalendar.css);
@Import url(Components/Severity.css);
@Import url(Components/Document.css);
@Import url(Components/ResultsTable.css);
@Import url(Components/TaskList.css);
@Import url(Components/TodoList.css);
@Import url(Components/ContractList.css);
@Import url(Components/ShipmentList.css);
@Import url(Components/EditIcons.css);
@Import url(Components/UserList.css);
@Import url(Components/SimpleList.css);
@Import url(Components/ApplicationForm.css);
@Import url(Components/jquery.ui.css);
@Import url(Components/Blank.css);
@Import url(Components/thickbox.css);

Each file in the components folder contains just a few lines of related styles, on the topic of the filename.

The more astute among you may have realised however that whilst this mass of @Imports might be super useful for development, its going to create an HTTP request spamathon on each page request.

Step up my CSS combining NAnt task.

As an aside, I am currently migrating towards Rake instead of NAnt as my build tool, and when I do I shall create a Ruby version of this.

Point the task at your CSS files, and it will run over them, replacing each @Import directive with the CSS that would actually be imported. Awesome! This means you can divide your CSS up into a million, super granular files and not need to worry about any HTTP request overheads, because in the live environment, you will only have a single file :D

To use the task:

  1. Import the dll into your .build file
  2. Point the CssCombiner task at your built CSS files (NOT YOUR SOURCE CODE)
  3. Go and do something else with the time you have saved

Here is an example:

<loadtasks assembly="./tools/CssCombiner.NAntTask.dll" />

<target name="combine-css">
    <CssCombiner>
        <fileset basedir="output/build/">
            <include name="/**/*.css" />
		</fileset>
	</CssCombiner>
</target>

Enjoy :)