<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>temporalcohesion.co.uk</title>
	
	<link>http://temporalcohesion.co.uk</link>
	<description>...trying not to write legacy code, man.</description>
	<lastBuildDate>Sun, 05 Sep 2010 14:06:21 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/co/temporalcohesion" /><feedburner:info uri="co/temporalcohesion" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Unit Testing Events</title>
		<link>http://feedproxy.google.com/~r/co/temporalcohesion/~3/ZLf92v22SlE/</link>
		<comments>http://temporalcohesion.co.uk/2010/07/21/unit-testing-events/#comments</comments>
		<pubDate>Wed, 21 Jul 2010 07:32:00 +0000</pubDate>
		<dc:creator>stuart</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Coding]]></category>

		<guid isPermaLink="false">http://temporalcohesion.co.uk/?p=205</guid>
		<description><![CDATA[Recently I have had to unit test some events in an application I work on. I came up with a workable solution, but I didn’t really like the way it was working, and it just looked ugly. So I did a little digging on Google, and found this helpful question on StackOverflow. Here is my [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I have had to unit test some events in an application I work on. I came up with a workable solution, but I didn’t really like the way it was working, and it just looked ugly. So I did a little digging on Google, and <a href="http://stackoverflow.com/questions/248989/unit-testing-that-an-event-is-raised-in-c">found this helpful question on StackOverflow</a>.</p>
<p>Here is my take it. I’m putting it here so I can find easily find it again. Basically it’s the same, but I’m using a lambda to create my anonymous delegate:</p>
<pre class="brush: csharp">[Test]
public void UnitTestNodeChanged()
{
 var receivedEvents = new List&lt;XmlNodeChangedEventArgs&gt;();
 var document = new XmlDocument();

 document.NodeChanged += ((sender, e) =&gt; receivedEvents.Add(e));
 document.Load("C:\file.xml");

 Assert.That(receivedEvents.Count, Is.EqualTo(1));
}</pre>
<p>Nice and short, and to the point. We can test the fact that the event was raised (or not); how many times the event was raised; and, we can test the event arguments.</p>
<p>I like it. Some people may not, but it suits my purposes.</p><img src="http://feeds.feedburner.com/~r/co/temporalcohesion/~4/ZLf92v22SlE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://temporalcohesion.co.uk/2010/07/21/unit-testing-events/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://temporalcohesion.co.uk/2010/07/21/unit-testing-events/</feedburner:origLink></item>
		<item>
		<title>Well I certainly didn’t know that Word could do this</title>
		<link>http://feedproxy.google.com/~r/co/temporalcohesion/~3/YVY0axyiLvs/</link>
		<comments>http://temporalcohesion.co.uk/2010/03/31/well-i-certainly-didn%e2%80%99t-know-that-word-could-do-this/#comments</comments>
		<pubDate>Wed, 31 Mar 2010 20:46:48 +0000</pubDate>
		<dc:creator>stuart</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://temporalcohesion.co.uk/2010/03/31/well-i-certainly-didn%e2%80%99t-know-that-word-could-do-this/</guid>
		<description><![CDATA[Whilst I was watching football I had this amazing idea that I was going to write a plugin for Word that would let you write blog posts and publish them onto your blog. I literally had no idea that Word would have this baked in by default. Obviously I&#8217;ve had to test this out immediately.]]></description>
			<content:encoded><![CDATA[<p>Whilst I was watching football I had this amazing idea that I was going to write a plugin for Word that would let you write blog posts and publish them onto your blog. I literally had no idea that Word would have this baked in by default.
</p>
<p>Obviously I&#8217;ve had to test this out immediately.</p><img src="http://feeds.feedburner.com/~r/co/temporalcohesion/~4/YVY0axyiLvs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://temporalcohesion.co.uk/2010/03/31/well-i-certainly-didn%e2%80%99t-know-that-word-could-do-this/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://temporalcohesion.co.uk/2010/03/31/well-i-certainly-didn%e2%80%99t-know-that-word-could-do-this/</feedburner:origLink></item>
		<item>
		<title>Revisting the Project Euler problem runner</title>
		<link>http://feedproxy.google.com/~r/co/temporalcohesion/~3/LBnUS6kHKzE/</link>
		<comments>http://temporalcohesion.co.uk/2010/03/23/revisting-the-project-euler-problem-runner/#comments</comments>
		<pubDate>Tue, 23 Mar 2010 13:38:57 +0000</pubDate>
		<dc:creator>stuart</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Project Euler]]></category>
		<category><![CDATA[design patterns]]></category>
		<category><![CDATA[euler]]></category>

		<guid isPermaLink="false">http://temporalcohesion.co.uk/?p=189</guid>
		<description><![CDATA[I&#8217;m sure that you must have heard about Project Euler, which &#8220;is a series of challenging mathematical/computer programming problems that will require more than just mathematical insights to solve&#8221;. I have blogged about tackling the Project Euler problems before, and at the time, I developed a simple program to try to automate running the problems. [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m sure that you must have heard about <a title="Project Euler website" href="http://projecteuler.net/" target="_blank">Project Euler</a>, which &#8220;is a series of challenging mathematical/computer programming problems that  will require more than just mathematical insights to solve&#8221;. I have blogged about tackling the Project Euler problems <a href="http://temporalcohesion.co.uk/2008/08/22/building-the-project-euler-framework-part-1/">before</a>, and at the time, I developed a simple program to try to automate running the problems.</p>
<p>That was about 18 months ago, I&#8217;ve learned a lot since then and I think that it is high time to take a look back at the code and see if I can spot if there is any room for improvement.</p>
<h2>The current project</h2>
<div id="attachment_191" class="wp-caption alignleft" style="width: 250px"><a href="http://temporalcohesion.co.uk/wp-content/uploads/2010/03/eulerprojectold.png"><img class="size-medium wp-image-191 " title="eulerprojectold" src="http://temporalcohesion.co.uk/wp-content/uploads/2010/03/eulerprojectold-300x241.png" alt="The current structure of the project" width="240" height="193" /></a><p class="wp-caption-text">Current structure</p></div>
<p>Let&#8217;s have a look at how I structured the project when I set it up. The first thing that you will notice, is that I messed up the package names. It should be &#8220;uk.co&#8221;, and not &#8220;co.uk&#8221;, according to the <a title="Java Language specification on sun.com" href="http://java.sun.com/docs/books/jls/third_edition/html/packages.html#7.7" target="_blank">Java language specification</a>. A minor point, and not really a big deal, we can easily sort it out.</p>
<p>Something else I did, was lump everything together into the same project and package &#8211; the runner program, the utils (e.g. helper classes that you write as you progress through problems), resources and the problems themselves.</p>
<p>I don&#8217;t think that this was necessarily a bad idea at the time, I don&#8217;t think that it is inherintly a bad idea now, it&#8217;s logical for everything to share the same package. Or should I say, it <em>was </em>logical for everything to share the same package.</p>
<p>I am going to put the code for the problem runner onto Github, but I don&#8217;t want to share the answers to the problems. To answer your question, I think that it goes against the point of Project Euler, that of having a set of problems that the inquisitive person can solve with some math and programming. I have also found that the problems also help in getting comfortable with the syntax of a new programming language &#8211; after all the solutions to the problems remain the same, however the implementation is subtley different depending on the language being used.</p>
<h2>Re-Design</h2>
<p>Examining the current code and design, we can immediately identify some changes which we are going to make  I&#8217;m going to seperate the uk.co.temporalcohesion.euler package into three packages, which are more distinct from each other, but still keep them all in the same project. Why? Well, it is obvious that there are three tasks which we have to manage:</p>
<ol>
<li>Running problems.</li>
<li>Provide an API to run the problems.</li>
<li>Store the problems somewhere</li>
</ol>
<p>To shed some light on my thinking here, lets examine these in more detail. This will also identify areas of possible improvement in the design.</p>
<p>1. I want someway of consistenly running a problem (or group of problems) to test the solution(s) to (a) Project Euler problem(s). This is basically our console runner application, which doesn&#8217;t have to know exactly how this happens, it recieves input, and returns output &#8211; how that output is generated is irrelevant to it.</p>
<p>2. I want an easy to use API which I can leverage to easily implement the solution to a Project Euler problem, so that I don&#8217;t have to worry about re-writing all the input/output code over and over again. I also want to be able to share this API, without sharing the answers to the problems themselves.</p>
<p>3. I need to have somewhere I can put the answers to the problems, and associated helper classes (Prime number generators, etc) which I can easly backup, and easily run the problems from.</p>
<p>These are sounding a bit like user stories, and I suppose they are. They can be formalised as so:</p>
<blockquote>
<p style="text-align: left;">As a Problem Solver, I want to run the solution, or group of solutions, to a Project Euler problem.</p>
<p style="text-align: left;">As a problem solver, I want to concentrate implementing the solution to a euler problem, not on implementing input/output for the problem.</p>
<p style="text-align: left;">As a problem solver, I want a place to develop and store the problems, from which I can run the problems to test the solution.</p>
</blockquote>
<p style="text-align: left;">Fairly concise and simple requirements, which we will revisit later. We still have to examine the code in a little more detail so that we can identify exactly what it is we are going to refactor.</p>
<h2 style="text-align: left;">Code review</h2>
<p>The main class to examine is Euler, in Euler.java.  The first to say without even looking at the code, is that the name is fairly awful. Then when we examine the code in more detail, we can see the name is even worse. The class has the main entry point for the program, as well as all the code to actually run the problems. This class is doing everything, there is definately no Seperation of Concerns. It is responsible for accepting user input, loading and running the problems and displaying the output. Wow.</p>
<p>The class is designed around the <a title="Command Patter on Wikipedia" href="http://en.wikipedia.org/wiki/Command_pattern" target="_blank">Command Pattern</a>, and it has worked quite well. Looking at it now, a further two patterns could be used, namely <a title="Strategy patter on Wikipedia" href="http://en.wikipedia.org/wiki/Strategy_pattern" target="_blank">Strategy </a>and <a title="Template method pattern on Wikipedia" href="http://en.wikipedia.org/wiki/Template_method_pattern" target="_blank">Template method</a>.I&#8217;m still in two minds about refactoring the design pattern in use, but that discussion can be put off for the time being, as I have other things to concern me.</p>
<p>There are 144 SLoC, not a massive amount, but when you consider the above and what the class should be doing, then it is clearly a bit weighty. There are 7 functions in total, not counting the constructor, not a massive count, but as the SLoC count indicates, some of those functions are a bit long. The worst offender is the following method.</p>
<pre class="brush: java;">

private void loadClasses() {
 InputStream fis = null;

 Properties p = new Properties();

 try {
 fis = ClassLoader
 .getSystemResourceAsStream(&quot;co/uk/temporalcohesion/euler/resources/problems.properties&quot;);
 p.load(fis);

 Enumeration&lt;?&gt; e = p.propertyNames();
 while (e.hasMoreElements()) {
 String key = (String) e.nextElement();
 String value = (String) p.getProperty(key);

 Object o = Class.forName(value).newInstance();
 if( ( o != null) &amp;&amp; (o instanceof Problem)){
 Problem problem = (Problem)o;
 problems.put(Integer.parseInt(key), problem);
 }
 }
 }

 catch (FileNotFoundException e) {
 e.printStackTrace();
 } catch (IOException e) {
 e.printStackTrace();
 } catch (ClassNotFoundException e) {
 e.printStackTrace();
 } catch (InstantiationException e) {
 e.printStackTrace();
 } catch (IllegalAccessException e) {
 e.printStackTrace();
 } catch (ClassCastException e) {

 }
 finally {
 try {
 fis.close();
 } catch (IOException e) {
 e.printStackTrace();
 }
 }
 }
</pre>
<p>Wow, that&#8217;s a lot of code for something which is relatively straightforward. It&#8217;s not exactly easy to read, and it violoates the Single Responsibility Principle: by loading in and enumerating over a properties file, instantiating new instances of problem classes, and handling all the exceptions which can be thrown. There will definately be some room for improvement there.</p>
<p>Getting back to the main <em>Euler </em>class as a whole, there is an even worse problem&#8230;</p>
<p>There are no unit tests!</p>
<p>This is a disastrous situation, because it means I cannot refactor the class with any confidence. The me of 18 months ago has a lot to answer for. I&#8217;ve got a bit of work to do. Check back next time to see how I&#8217;ve progressed things.</p>
<p style="text-align: left;"><img src="http://feeds.feedburner.com/~r/co/temporalcohesion/~4/LBnUS6kHKzE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://temporalcohesion.co.uk/2010/03/23/revisting-the-project-euler-problem-runner/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://temporalcohesion.co.uk/2010/03/23/revisting-the-project-euler-problem-runner/</feedburner:origLink></item>
		<item>
		<title>Even more on the generic plugin manager</title>
		<link>http://feedproxy.google.com/~r/co/temporalcohesion/~3/svOUKDmv6os/</link>
		<comments>http://temporalcohesion.co.uk/2010/03/17/even-more-on-the-generic-plugin-manager/#comments</comments>
		<pubDate>Wed, 17 Mar 2010 13:24:40 +0000</pubDate>
		<dc:creator>stuart</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[DI]]></category>
		<category><![CDATA[IoC]]></category>
		<category><![CDATA[Plugin Manager]]></category>

		<guid isPermaLink="false">http://temporalcohesion.co.uk/?p=180</guid>
		<description><![CDATA[I&#8217;ve written previously about writing your own generic plugin manager/framework. I believe that this is a worthwhile exercise for the beginning programmer, because it firstly teaches you a lot about reflection, and secondly teaches you the advantages that proper use of interfaces can bring to your code. Thirdly it can also teach you to think [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve <a title="Writing a generic plugin manager in C# @ Temporal Cohesion" href="http://temporalcohesion.co.uk/2009/05/25/writing-a-generic-plugin-manager-in-c/" target="_self">written </a><a title="More on the generic plugin manager" href="http://temporalcohesion.co.uk/2009/11/02/more-on-the-generic-plugin-manager/" target="_self">previously</a> about writing your own generic plugin manager/framework.</p>
<p>I believe that this is a worthwhile exercise for the beginning programmer, because it firstly teaches you a lot about reflection, and secondly teaches you the advantages that proper use of interfaces can bring to your code. Thirdly it can also teach you to think about how your API might be used by someone else when they write a plugin for your program. In short I think it&#8217;s a great exercise.</p>
<p>While writing and using my own plugin framework has been a great learning experience for me, I&#8217;ve found that I have outgrown it&#8217;s usefulness to me. What made me see this was when I started to think about and begin implementing a way for me to use the framework as a <a title="Dependency Injection on Wikipedia" href="http://en.wikipedia.org/wiki/Dependency_injection" target="_blank">IoC/Dependency Injection</a> tool. This led me off on some Googling and I found <a title="Funq DI container on Codeplex" href="http://funq.codeplex.com/" target="_blank">Funq</a>, and the the <a href="http://www.clariusconsulting.net/blogs/kzu/archive/2009/02/02/116399.aspx" target="_blank">associated screencasts by Cazzulino</a>.</p>
<p>This got me to thinking about <a title="Don't Repeat Yourself on Wikipedia" href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself" target="_blank">DRY</a>. Don&#8217;t Repeat Yourself can just as easily mean Don&#8217;t Repeat Work Other People Have Already Done (If You Don&#8217;t Have To), but DRWOPHADIYDHT doesn&#8217;t sound/look nice as an acronym. Perhaps a better way to express that sentiment is &#8220;lazyDRY&#8221;, or &#8220;The re-use of prexisting libraries and code can save you a lot of time, and which effort you can put into your application at a higher level.&#8221;</p>
<p>Or in other words, it is foolish to ignore the work that other people have done, unless you have a compelling reason to do so. If you really want to write your own IoC/DI container, then great, knock yourself out. No one is going to stop you.</p>
<p>I&#8217;m lazy though. Nanos gigantium humeris insidentes.</p>
<p>Depending on the blogs in your feed reader, or who you follow on Twitter, or just in general googling, you will probably come across references to the same group of IoC/DI containers. Chiefly:</p>
<ul>
<li><a title="StructureMap on Github" href="http://structuremap.github.com/structuremap/index.html" target="_blank">StructureMap</a></li>
<li><a title="Castle Windsor" href="http://www.castleproject.org/" target="_blank">Castle Windsor</a></li>
<li><a title="AutoFac on Google code" href="http://code.google.com/p/autofac/" target="_blank">AutoFac</a></li>
<li><a title="Ninject" href="http://ninject.org/" target="_blank">Ninject</a></li>
<li><a href="http://www.codeplex.com/MEF/" target="_blank">MEF</a></li>
<li><a href="http://msdn.com/unity">Unity</a></li>
<li><a href="http://www.springframework.net/">Spring.net</a></li>
</ul>
<p>There are others, but it would seem hardly anyone uses them. Of those above, I have so far only used StructureMap and Ninject, and have really liked using both of them. I will try out the others at some point, but so far I&#8217;ve liked what I&#8217;ve seen in StructureMap and Ninject, I honestly don&#8217;t think that any of the others will have anything better to offer me. Besides which, StructureMap has a built in method of using it as a plugin framework. Win.</p>
<h2>In Conclusion</h2>
<p>What can I draw from all this? I don&#8217;t think that I wasted any of my time or effort in writing my own plugin framework. It was a worthwhile exercise which taught me a lot of things, and I urge you to do the same.</p><img src="http://feeds.feedburner.com/~r/co/temporalcohesion/~4/svOUKDmv6os" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://temporalcohesion.co.uk/2010/03/17/even-more-on-the-generic-plugin-manager/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://temporalcohesion.co.uk/2010/03/17/even-more-on-the-generic-plugin-manager/</feedburner:origLink></item>
		<item>
		<title>You don’t have to kneel at the altar of the cult of Apple</title>
		<link>http://feedproxy.google.com/~r/co/temporalcohesion/~3/QXH6gFBalyY/</link>
		<comments>http://temporalcohesion.co.uk/2010/03/07/you-dont-have-to-kneel-at-the-altar-of-the-cult-of-apple/#comments</comments>
		<pubDate>Sun, 07 Mar 2010 18:54:52 +0000</pubDate>
		<dc:creator>stuart</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://temporalcohesion.co.uk/?p=175</guid>
		<description><![CDATA[Unless you&#8217;ve been living under a rock You will have seen, heard and read the buzz about the Apple iPad. What it is, what it does and why you should buy it. This post is not about all that &#8211; it&#8217;s covered in excruciating detail elsewhere on your favourite tech site. Ever since the iPad [...]]]></description>
			<content:encoded><![CDATA[<h1>Unless you&#8217;ve been living under a rock</h1>
<p>You will have seen, heard and read the buzz about the Apple <a title="ipad on Apple.com" href="http://www.apple.com/ipad/" target="_blank">iPad</a>. What it is, what it does and why you should buy it. This post is not about all that &#8211; it&#8217;s covered in excruciating detail elsewhere on your favourite tech site. Ever since the iPad was just a rumour, and since it was officially announced, we have been arguing about it at work. Whose going to buy one? Who is an idiot for wanting to buy one? Who is an idiot for not wanting to buy one?</p>
<blockquote><p>Note: I should mention that I do happen to own an iPhone (via an O2 two year(!) contract), and I think it is probably the best mobile phone I&#8217;ve ever owned, however, I will take some convincing to enter into another two year contract again. But I digress. I have a couple of old iPods, nothing else: I am not a <a title="Fanboy on wikipedia" href="http://en.wikipedia.org/wiki/Fan_%28person%29" target="_blank">fanboy</a>.</p></blockquote>
<p>The niche that the iPad and devices like it fill is undoubtedly there, or else these products would not be developed. The key thing here is &#8220;&#8230;and devices like it&#8230;&#8221;. There isn&#8217;t just the iPad to consider.  This is the fantastic thing about our society: we have a huge freedom of choice in our purchasing decisions. We are free to evaluate, consider and weigh all the pros and cons of a particular product before we make the commitment to purchase.</p>
<h1>Unless you are an Apple fanboy</h1>
<p>In which case, you have already sub-concisiously made the decision to purchase anything with an Apple logo on. Are you an Apple fan boy? You have a Mac of some discription. You bought (and probably still have) a first-gen iPod. You bought an iTouch the day it was release. You were the first in your office to get an iPhone. You were the first to upgrade to an iPhone 3G. You were the first to upgrade to an iPhone 3GS. You hammer F5 on your favourite liveblog of an Apple event. You wouldn&#8217;t even consider buying a laptop from Asus, Acer or Dell (or whoever) which as powerful and costs half the price of something which has a fucking Apple logo on it.</p>
<p>Fanboy. Acolyte. Get out. You have already made your choice. You cannot win an arguement with someone who fanatically believes they are right.</p>
<h1>Open minded? Continue from here</h1>
<p>For those who are prepared to broaden our horizons, there is a bewildering array of choice just around the corner. Rather than rehash other people&#8217;s hard work from around the interweb, and because I&#8217;m lazy, I refer you to this article on About.com: <a href="http://portables.about.com/od/otherdevices/tp/Slate_tablet_roundup.htm" target="_blank">http://portables.about.com/od/otherdevices/tp/Slate_tablet_roundup.htm</a>, which offers a succinct highlight of varous slate tablet computers. <a href="http://www.engadget.com/2010/03/05/microsofts-courier-digital-journal-exclusive-pictures-and-de/" target="_blank">Engadget also has some details</a> of Microsofts offering, the &#8216;Courier&#8217;, which looks promising.</p>
<h1>In Conclusion</h1>
<p>You do not have to kneel at the alter of the cult of Apple. You have a choice. Use it wisely.</p><img src="http://feeds.feedburner.com/~r/co/temporalcohesion/~4/QXH6gFBalyY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://temporalcohesion.co.uk/2010/03/07/you-dont-have-to-kneel-at-the-altar-of-the-cult-of-apple/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://temporalcohesion.co.uk/2010/03/07/you-dont-have-to-kneel-at-the-altar-of-the-cult-of-apple/</feedburner:origLink></item>
		<item>
		<title>Git plus dropbox</title>
		<link>http://feedproxy.google.com/~r/co/temporalcohesion/~3/CQQj7KYTi8g/</link>
		<comments>http://temporalcohesion.co.uk/2010/03/04/git-plus-dropbox/#comments</comments>
		<pubDate>Thu, 04 Mar 2010 23:06:12 +0000</pubDate>
		<dc:creator>stuart</dc:creator>
				<category><![CDATA[Git]]></category>
		<category><![CDATA[Dropbox]]></category>
		<category><![CDATA[Source Control]]></category>

		<guid isPermaLink="false">http://temporalcohesion.co.uk/?p=147</guid>
		<description><![CDATA[Some time ago, I wrote about using Dropbox as a version control system. I now realise how naive  and short-sighted that thought was. At the time, it was my belief that a dropbox account could be suitable for maintaining version history, and after a fashion, it can be, because using the web client to view [...]]]></description>
			<content:encoded><![CDATA[<p><a title="Link to earlier blog post." href="http://temporalcohesion.co.uk/2008/08/29/source-control-using-dropbox/" target="_self">Some time ago</a>, I wrote about using <a title="Link to dropbox.com" href="https://www.dropbox.com/" target="_blank">Dropbox </a>as a version control system. I now realise how naive  and short-sighted that thought was. At the time, it was my belief that a dropbox account could be suitable for maintaining version history, and after a fashion, it can be, because using the web client to view your files, you can see previous versions of  the files in your dropbox.</p>
<p>However, there are problems with this approach. Consider that you&#8217;ve changed several files, but then you realise that the changes you have made are not good enough, or just don&#8217;t work. With svn, or vss (*vomit*), you can undo-checkout to get the previous version back, with dropbox you can roll back to the previous version &#8211; one file at a time. There is no branching, no merging, no tagging. Nothing like a traditional SCM tool should have.</p>
<p>Dropbox is after all, essentially just a folder that is backed up &#8220;to the cloud&#8221;. If we use the right tool, we can take advantage of this properly.</p>
<h1>Enter Git</h1>
<p>What is <a title="Git SCM" href="http://git-scm.com/" target="_blank">Git</a>? Well, surely you must have at least heard of Git by now? If not, I refer you to the <a title="Wikipedia article about git" href="http://en.wikipedia.org/wiki/Git_(software)" target="_blank">wikipedia page</a> about Git. Ok? You&#8217;re back?</p>
<p>The key aspect of Git which we can take advantage of is essentially the very nature of Git itself. Every Git clone is a full-repository, containing the full commit  history and full revision tracking capability for the project, and it does not rely on network access nor a central server.</p>
<p>Basically, the idea is that you initialise an empty, bare repository inside your dropbox folder, and then somewhere else on your filesystem, perhaps a development folder where you store all your projects, you clone the repo from dropbox, and do all your work on that clone. Then when you call &#8216;git push origin master&#8217;, your changes are pushed into the dropbox repo, ready to be synced up on other computers you use.</p>
<blockquote><p>Note: This is not a substitue for having a proper hosted Git repository, such as a project on Github, or somewhere else. However, it useful if you are working on something you aren&#8217;t ready to put into the public domain, or you haven&#8217;t yet decided to purchase an account on a private repository provider.</p></blockquote>
<h1>Setup</h1>
<p>Setting it up is fairly simple, but, I am going to assume that you have Dropbox and a dropbox account, Git and (if you are on Windows) GitExtensions, correctly installed already.</p>
<blockquote><p>Note: I have only tested this on Windows 7, but I wouldn&#8217;t expect it to not work on any other system. As always YMMV.</p></blockquote>
<p>First, create a folder in your dropbox folder to house your projects, e.g. C:\Users\Stuart\Documents\My Dropbox\projects or just store it in the root of your Dropbox, it&#8217;s upto you. Don&#8217;t forget to include quotes around any path that has a space in, or else it won&#8217;t work.</p>
<pre class="brush: bash;">

Stuart@LAPTOP ~/Documents/My Dropbox/projects
$ mkdir example

Stuart@LAPTOP ~/Documents/My Dropbox/projects
$ cd example

Stuart@LAPTOP ~/Documents/My Dropboxprojects/example
$ mkdir .git

Stuart@LAPTOP ~/Documents/My Dropbox/projects/example
$ cd .git/

Stuart@LAPTOP ~/Documents/My Dropbox/projects/example/example.git
$ git init --bare
Initialized empty Git repository in c:/Users/Stuart/Documents/My Dropbox/projects/example
/example.git/
</pre>
<p>Then, in your development folder clone that repo.</p>
<pre class="brush: bash;">
Stuart@LAPTOP /c/development/examples
$ git clone -v &quot;C:/Users/Stuart/Documents/My Dropbox/projects/example/.git&quot;
Initialized empty Git repository in c:/development/examples/example/.git/

Stuart@LAPTOP /c/development/examples
$ cd example/

Stuart@LAPTOP /c/development/examples/example (master)
$ touch example.txt

Stuart@STUART-LAPTOP /c/development/examples/example (master)
$ git add example.txt

Stuart@LAPTOP /c/development/examples/example (master)
$ git commit -m &quot;Added example file to initial commit&quot;
[master e9ac78d] Added example file to initial commit
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 example.txt

Stuart@LAPTOP /c/development/examples/example (master)
$ git push origin master
Counting objects: 3, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 253 bytes, done.
Total 2 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (2/2), done.
To C:/Users/Stuart/Documents/My Dropbox/projects/example/.git
 1e38d4e..e9ac78d  master -&gt; master
</pre>
<p>Dropbox will sync the files into the cloud. On your other computer, the git repo will sync, then you can clone it, and find that you have all your history for your project as you would expect.</p><img src="http://feeds.feedburner.com/~r/co/temporalcohesion/~4/CQQj7KYTi8g" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://temporalcohesion.co.uk/2010/03/04/git-plus-dropbox/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://temporalcohesion.co.uk/2010/03/04/git-plus-dropbox/</feedburner:origLink></item>
		<item>
		<title>I won a free Typemock t-shirt via Twitter!</title>
		<link>http://feedproxy.google.com/~r/co/temporalcohesion/~3/8ZUpm08DRo4/</link>
		<comments>http://temporalcohesion.co.uk/2010/02/17/i-won-a-free-typemock-t-shirt-via-twitter/#comments</comments>
		<pubDate>Wed, 17 Feb 2010 13:47:47 +0000</pubDate>
		<dc:creator>stuart</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[winner]]></category>

		<guid isPermaLink="false">http://temporalcohesion.co.uk/?p=150</guid>
		<description><![CDATA[Recently I re-tweeted something from Roy Osherove, and as a consequence, I received a nice t-shirt today all the way from Israel! As a bonus, also visible is my copy of The Art of Unit Testing, by Mr Osherove.]]></description>
			<content:encoded><![CDATA[<p>Recently I <a title="twitter.com/RoyOsherove" href="http://twitter.com/RoyOsherove/status/8633903086" target="_blank">re-tweeted something</a> from Roy Osherove, and as a consequence, I received a nice t-shirt today all the way from Israel! As a bonus, also visible is my copy of <a title="The Art of Unit Testing on Amazon.co.uk" href="http://www.amazon.co.uk/gp/product/1933988274?ie=UTF8&amp;tag=tempocohes-21&amp;linkCode=as2&amp;camp=1634&amp;creative=6738&amp;creativeASIN=1933988274">The Art of Unit Testing</a>, by Mr  Osherove.</p>
<p style="text-align: center;">
<div id="attachment_151" class="wp-caption aligncenter" style="width: 310px"><a href="http://temporalcohesion.co.uk/wp-content/uploads/2010/02/tshirt_book.jpg"><img class="size-medium wp-image-151 " title="tshirt_book" src="http://temporalcohesion.co.uk/wp-content/uploads/2010/02/tshirt_book-300x225.jpg" alt="&quot;Legalize Unit Testing&quot; t-shirt" width="300" height="225" /></a><p class="wp-caption-text">The t-shirt I won, and my copyof The Art of Unit Testing</p></div><img src="http://feeds.feedburner.com/~r/co/temporalcohesion/~4/8ZUpm08DRo4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://temporalcohesion.co.uk/2010/02/17/i-won-a-free-typemock-t-shirt-via-twitter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://temporalcohesion.co.uk/2010/02/17/i-won-a-free-typemock-t-shirt-via-twitter/</feedburner:origLink></item>
		<item>
		<title>More on the generic plugin manager</title>
		<link>http://feedproxy.google.com/~r/co/temporalcohesion/~3/eDtFvbBbxLc/</link>
		<comments>http://temporalcohesion.co.uk/2009/11/02/more-on-the-generic-plugin-manager/#comments</comments>
		<pubDate>Mon, 02 Nov 2009 09:00:24 +0000</pubDate>
		<dc:creator>stuart</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[Plugin Manager]]></category>

		<guid isPermaLink="false">http://temporalcohesion.co.uk/?p=134</guid>
		<description><![CDATA[Update: I&#8217;ve written some more about what I&#8217;ve learned whilst working on my plugin manager here: http://temporalcohesion.co.uk/2010/03/17/even-more-on-the-generic-plugin-manager/ A few months ago I wrote about writing a generic plugin loader/manager in C#, where I offered links to several articles and referenced a rather excellent book about C# which I had used to base my plugin loader [...]]]></description>
			<content:encoded><![CDATA[<h4>Update:</h4>
<p>I&#8217;ve written some more about what I&#8217;ve learned whilst working on my plugin manager here: <a href="http://temporalcohesion.co.uk/2010/03/17/even-more-on-the-generic-plugin-manager/" target="_self">http://temporalcohesion.co.uk/2010/03/17/even-more-on-the-generic-plugin-manager/</a></p>
<p>A few months ago <a title="Writing a generic plugin manager" href="http://temporalcohesion.co.uk/2009/05/25/writing-a-generic-plugin-manager-in-c/" target="_self">I wrote about</a> writing a generic plugin loader/manager in C#, where I offered links to several articles and referenced a rather excellent book about C# which I had used to base my plugin loader on. I hadn&#8217;t really given it much thought since then, but according to Google Analytic&#8217;s, it&#8217;s one of the most hit posts on my blog. Recently I had a request to release the source code.</p>
<p>Now when I first wrote that post, I was hesitant to include any code, and I still am &#8211; not because I think there is something new and unique with what I&#8217;ve done &#8211; but, rather that what I have written is not terribly difficult to write. I do not mean to sound snobbish or arrogant at all, I&#8217;m just telling you how it is, all I&#8217;ve done is to do a bit of reflection on assemblies in a folder, and load instances of certain interfaces.</p>
<p>Anyway&#8230;</p>
<p>The scenario is that you want to provide a way for for 3rd parties to be able to add additional functionality to your application at run time. We need to provide a common way for 3rd parties to be able to register their new functionality into our application, in order that the user can take advantage of the exciting new feature being added to the application.</p>
<p>Straight away, you should be thinking to yourself: Interface!</p>
<pre class="brush: csharp;">

public interface IPlugin
 {
 /// &lt;summary&gt;
 /// Does what ever It is.
 /// &lt;/summary&gt;
 void Do(Action it);
 }
</pre>
<p>Anyone who now wants to create a plugin for our application must implement our IPlugin interface, as it defines the contract to which our application is bound to, in order to recognise and load plugins. Thus any assembly, that has a class which implements IPlugin is considered by our application to be a plugin which is capable of offering additional functionality.</p>
<p>We can now attempt to load our plugins. We need to have a class which can scan a folder for assemblies, scan those assemblies for types which implement IPlugin, and then create instances of them which our application can use. Loading the assemblies is easy:</p>
<pre class="brush: csharp;">
public class PluginLoader&lt;T&gt;
{
 private IList&lt;T&gt; pluginsList = new List&lt;T&gt;();
 ...
}

...

public virtual IList&lt;T&gt; LoadPlugins()
 {
 foreach (string file in Directory.GetFiles(this.pluginFolderPath, &quot;*.dll&quot;, SearchOption.AllDirectories))
 {
 Assembly assembly = Assembly.LoadFile(file);
 this.LoadObjects(assembly);
 }

 return this.pluginsList;
 }
</pre>
<p>We create a generic class, so we can use it with any type of plugin, and not just ones which implement IPlugin, then it&#8217;s just simple directory recursion to load all the files in the specified folder which have a file extension of .dll. The real magic happens in the LoadObjects() method.</p>
<pre class="brush: csharp;">
var types = from t in assembly.GetTypes()
 where t.IsClass &amp;&amp;
 (t.GetInterface(typeof(T).Name) != null)
 select t;

 foreach (Type t in types)
 {
 T plugin = (T)assembly.CreateInstance(t.FullName, true);
 this.pluginsList.Add(plugin);
 }
</pre>
<p>Using LINQ, we extract all the types from the assembly which are classes, which implement the interface which is a typeof(T) &#8211; T being the type we specified when we instantiated the class. You could just as easily here specify the type should inherit from some other type, and you could also check to see if a class has some assembly level attribute.</p>
<p>Why would you want to do that? Well, we can use an assembly level attribute to decorate the plugin class with meta-data about the plugin, such as the author, a short description, the name of the plugin, and it&#8217;s version.</p>
<pre class="brush: csharp;">
public virtual KeyValuePair&lt;string, List&lt;KeyValuePair&lt;string, string&gt;&gt;&gt; GetPluginInformation(Type type)
 {
 var attributeInfo = from pa in type.GetCustomAttributes(false)
 where (pa.GetType() == typeof(PluginAttribute))
 select pa;

 foreach (PluginAttribute p in attributeInfo)
 {
 data.Add(new KeyValuePair&lt;string, string&gt;(&quot;Author&quot;, p.Author));
 data.Add(new KeyValuePair&lt;string, string&gt;(&quot;Description&quot;, p.Description));
 data.Add(new KeyValuePair&lt;string, string&gt;(&quot;Name&quot;, p.Name));
 name = p.Name;
 data.Add(new KeyValuePair&lt;string, string&gt;(&quot;Type&quot;, p.Type.ToString()));
 data.Add(new KeyValuePair&lt;string, string&gt;(&quot;Version&quot;, p.Version));
 }

 this.attributeInformation = new KeyValuePair&lt;string, List&lt;KeyValuePair&lt;string, string&gt;&gt;&gt;(name, data);

 return this.attributeInformation;
 }
</pre>
<p>Or you could create a struct to use as a DTO for the plugin meta-data, it&#8217;s up to you.</p>
<p>I&#8217;ve removed all the comments and exception handling from the code I&#8217;ve posted purely just to save space, you&#8217;d really want to include that &#8211; especially the exception handling. But that&#8217;s really all there is to it, you might want to have a property to access the actual plugin list, or return it from a LoadPlugins method, it&#8217;s up to you.</p>
<p>You&#8217;ll notice I&#8217;ve made the methods virtual, you may want to use this class as a base class in another class. For instance I&#8217;ve got an additional class which inherits from my plugin loader class which does specific tasks for a particular type of plugin, and another which does different tasks for a different type of plugin.</p><img src="http://feeds.feedburner.com/~r/co/temporalcohesion/~4/eDtFvbBbxLc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://temporalcohesion.co.uk/2009/11/02/more-on-the-generic-plugin-manager/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://temporalcohesion.co.uk/2009/11/02/more-on-the-generic-plugin-manager/</feedburner:origLink></item>
		<item>
		<title>A psake build script example</title>
		<link>http://feedproxy.google.com/~r/co/temporalcohesion/~3/Q7vfU4_xKBQ/</link>
		<comments>http://temporalcohesion.co.uk/2009/10/26/a-psake-build-script-example/#comments</comments>
		<pubDate>Mon, 26 Oct 2009 09:00:05 +0000</pubDate>
		<dc:creator>stuart</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[Powershell]]></category>
		<category><![CDATA[build script]]></category>
		<category><![CDATA[psake]]></category>

		<guid isPermaLink="false">http://temporalcohesion.co.uk/?p=119</guid>
		<description><![CDATA[I have recently started using psake to do some build automation at work, and I&#8217;ve found that there is not a great deal of information about how to write a build script using psake available on the internet. It isn&#8217;t all that amazingly difficult if truth be told, however there are a couple of &#8216;gotchas&#8217;, [...]]]></description>
			<content:encoded><![CDATA[<p>I have recently started using psake to do some build automation at work, and I&#8217;ve found that there is not a great deal of information about how to write a build script using psake available on the internet. It isn&#8217;t all that amazingly difficult if truth be told, however there are a couple of &#8216;gotchas&#8217;, and I would like to share what I have learned in the hopes that it benefits someone.</p>
<p>If you have not heard of it, <a title="psake project on Google Code" href="http://code.google.com/p/psake/" target="_blank">psake</a> is a&#8221;&#8230;build automation tool written in PowerShell&#8221;, started by <a title="James Kovacs' blog" href="http://codebetter.com/blogs/james.kovacs/default.aspx" target="_blank">James Kovacs</a>. With it, you can write build scripts, with which you can automate the build and deployment of your .NET project. Recently the version <a title="psake 2.00 release annoucement" href="http://codebetter.com/blogs/james.kovacs/archive/2009/10/14/releasing-psake-v1-00-amp-psake-v2-00.aspx">1.00 and 2.0<strong> </strong>0 version were released</a>. Why two versions? Well, the 1.00 version is primarily for PowerShell 1.0, but psake 1.00 is being &#8220;retired&#8221;. This article assumes the reader is using psake 2.01 and PowerShell 2.0.</p>
<p>A quick note here, I should point out the primary example I based my first build script on is <a title="Ayende Rahien Rhino Mocks build script" href="http://ayende.com/Blog/archive/2009/08/30/on-psake.aspx" target="_blank">Ayende Rahien&#8217;s build script for Rhino Mocks</a>.</p>
<h2>Our first psake build script</h2>
<p>First, I have to make two assumptions:</p>
<ol>
<li>I have to assume that you have PowerShell installed, if you are running Vista/Windows 7 then it&#8217;s installed by default, if you are on XP, then it is a manual install.</li>
<li>You have installed the psake module into Powershell &#8211; see the release announcement linked to above for details on how to do this.</li>
</ol>
<div id="attachment_120" class="wp-caption alignleft" style="width: 147px"><a href="http://temporalcohesion.co.uk/wp-content/uploads/2009/10/psake_example_solution.png"><img class="size-full wp-image-120    " title="psake_example_solution" src="http://temporalcohesion.co.uk/wp-content/uploads/2009/10/psake_example_solution.png" alt="Example solution" width="137" height="161" /></a><p class="wp-caption-text">Example solution</p></div>
<p>With those assumptions out of the way, we are going to write a build script to automate the building of a simple C# solution, containing a Windows Forms application, and two class library assemblies.</p>
<p>Hopefully this should be simple enough to easily follow along with what is happening in the build script, but complex enough that you can see how sophisticated your build scripts can be.</p>
<p>You can see that I have already taken the liberty of adding an extra file to the solution, &#8220;build.ps1&#8243;, this is our build script, with which we can command psake to do great things for us.</p>
<p>With our solution setup, we can now write our first build script:</p>
<pre class="brush: powershell;">
properties {
 $base_dir = Resolve-Path .
 $sln_file = &quot;$base_dir\WindowsFormsApplication.sln&quot;
}

Task default -depends Compile

Task Compile {
 msbuild &quot;$sln_file&quot;
}
</pre>
<p>Open a command prompt into the directory containing the .sln file, which is where your build.ps1 script<br />
should be, and run this command: invoke-psake .\build.ps1 -taskList Compile</p>
<div id="attachment_123" class="wp-caption aligncenter" style="width: 310px"><a href="http://temporalcohesion.co.uk/wp-content/uploads/2009/10/psake_Compile.png"><img class="size-medium wp-image-123" title="psake_Compile" src="http://temporalcohesion.co.uk/wp-content/uploads/2009/10/psake_Compile-300x296.png" alt="psake Compile task output" width="300" height="296" /></a><p class="wp-caption-text">psake Compile task output</p></div>
<p>You should receive some output to the console window like the above.What the script does is to work out where on the file system the script is running, and gets the path to that folder, and builds the path to the specified solution file, and runs msbuild, passing the full path to the solution file as a parameter.</p>
<p>The script as it is has some drawbacks though. In it&#8217;s current form, msbuild will only build the default configuration of the solution. What if we want to build a Debug version, or a Release version, or some other configuration we&#8217;ve created? Additionally, it doesn&#8217;t let us specify a directory to put the built binaries, they just get put in the default locations as specified in the projects contained in the solution &#8211; what if we want to put them in a custom location?</p>
<p>If we modify our build script slightly, we can introduce this functionality. Firstly, we need to specify some additional properties:</p>
<pre class="brush: powershell;">
properties {
 $base_dir = Resolve-Path .
 $build_dir = &quot;$base_dir\build&quot;
 $sln_file = &quot;$base_dir\WindowsFormsApplication.sln&quot;
 $debug_dir = &quot;$build_dir\Debug\\&quot;
 $release_dir = &quot;$build_dir\Release\\&quot;;
}
</pre>
<p>Notice the double backslash, msbuild requires a trailing slash when paths are specified, and it seems to require the additional backslash as well, or else it doesn&#8217;t work. With those additional properties in place, we can introduce two new tasks to our build script:</p>
<pre class="brush: powershell;">
Task Clean {
 remove-item -force -recurse $debug_dir -ErrorAction SilentlyContinue
 remove-item -force -recurse $release_dir -ErrorAction SilentlyContinue
}

Task Init -depends Clean {
 new-item $debug_dir -itemType directory
 new-item $release_dir -itemType directory
}
</pre>
<p>Powershell&#8217;s easy to read syntax should make it easy to follow with what is happening now. In the Clean task, we forcefully and recursively remove any files and the folder from the specified path, and if there are any errors then they are not displayed. Now that we know that those folders are going to be cleaned and created, we can create two further tasks, where we can create Debug and Release versions of our solution:</p>
<pre class="brush: powershell;">
Task Debug -depends Init {
 msbuild $sln_file &quot;/nologo&quot; &quot;/t:Rebuild&quot; &quot;/p:Configuration=Debug&quot; &quot;/p:OutDir=&quot;&quot;$debug_dir&quot;&quot;&quot;
}

Task Release -depends Init {
 msbuild $sln_file &quot;/nologo&quot; &quot;/t:Rebuild&quot; &quot;/p:Configuration=Release&quot; &quot;/p:OutDir=&quot;&quot;$release_dir&quot;&quot;&quot;
</pre>
<p>Again, the syntax here is relatively straightforward to follow along with, we execute msbuild, passing it the solution file to build, specify not to show the logo (suppressing the output of &#8220;copyright microsoft msbuild etc), tell it to execute the rebuild target and to build the Debug configuration, copying the output to the specified debug directory. Notice that that there are no spaces in the paramters that we pass to msbuild. For example, if we passed the parameters like this: &#8220;/p:Configuration=Release /p:OutDir=&#8221;"$release_dir&#8221;"&#8221;, then it would fail and we would get a msbuild parse error saying it was invalid.</p>
<div id="attachment_129" class="wp-caption alignleft" style="width: 206px"><a href="http://temporalcohesion.co.uk/wp-content/uploads/2009/10/psake_example_debug.png"><img class="size-medium wp-image-129" title="psake_example_debug" src="http://temporalcohesion.co.uk/wp-content/uploads/2009/10/psake_example_debug-196x300.png" alt="Build script output for Debug task" width="196" height="300" /></a><p class="wp-caption-text">Build script output for Debug task</p></div>
<h2>Summary</h2>
<p>In a relatively short amount of code, less than 30 lines, we have accomplished quite a lot. We can now issue the command: invoke-psake .\build.ps1 -taskList Debug, and psake will automatically clean the output folders, do a full rebuild of the Debug configuration and copy the output to a custom location on our filesystem. What&#8217;s more, the build script we have written is small, compact, easy to read, easy to maintain and easy to build/extend upon in the future.</p>
<p>As this is getting a bit long already, I&#8217;m going to cut things short here, however, there are some additional things that you can do as part of the build script that are very nice, such as automatically versioning the assembly before you do the full build. If you take a look at <a title="Ayende Rahien Rhino Mocks build script" href="http://ayende.com/Blog/archive/2009/08/30/on-psake.aspx" target="_blank">Ayende Rahien&#8217;s example</a> from Rhino Mocks, that is covered there.</p>
<p>Also in the new version of psake, there are pre and post conditions and actions that you can add onto your tasks, although I haven&#8217;t had the opportunity to use them yet. I&#8217;ll try to cover those in a future blog post though.</p><img src="http://feeds.feedburner.com/~r/co/temporalcohesion/~4/Q7vfU4_xKBQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://temporalcohesion.co.uk/2009/10/26/a-psake-build-script-example/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://temporalcohesion.co.uk/2009/10/26/a-psake-build-script-example/</feedburner:origLink></item>
		<item>
		<title>My recommended reading list</title>
		<link>http://feedproxy.google.com/~r/co/temporalcohesion/~3/BOjpMcYmu8M/</link>
		<comments>http://temporalcohesion.co.uk/2009/10/17/my-recommended-reading-list/#comments</comments>
		<pubDate>Sat, 17 Oct 2009 23:06:21 +0000</pubDate>
		<dc:creator>stuart</dc:creator>
				<category><![CDATA[Books]]></category>
		<category><![CDATA[Coding]]></category>

		<guid isPermaLink="false">http://temporalcohesion.co.uk/?p=97</guid>
		<description><![CDATA[Love him or hate him, several years ago, Jeff Atwood (of Codinghorror.com infamy and the really rather awesome StackOverflow.com) posted on his blog a recommended reading list for developers. He has since become a sort of mini internet programming celebrity. Since imitation is the greatest form of flattery, I present to you my own list [...]]]></description>
			<content:encoded><![CDATA[<p>Love him or hate him, several years ago, Jeff Atwood (of Codinghorror.com infamy and the really rather awesome StackOverflow.com) <a title="Recommended reading on codinghorror.com" href="http://www.codinghorror.com/blog/archives/000020.html" target="_blank">posted on his blog</a> a recommended reading list for developers. He has since become a sort of mini internet programming celebrity. Since imitation is the greatest form of flattery, I present to you my own list of recommended reading.</p>
<p style="text-align: left;">
<div id="attachment_100" class="wp-caption alignleft" style="width: 141px"><a href="http://www.amazon.co.uk/gp/product/0735619670?ie=UTF8&amp;tag=tempocohes-21&amp;linkCode=as2&amp;camp=1634&amp;creative=6738&amp;creativeASIN=0735619670"><img class="size-full wp-image-100 " title="Code Complete 2nd Edition" src="http://temporalcohesion.co.uk/wp-content/uploads/2009/10/51seLiYuURL._SL160_.jpg" alt="Code Complete 2nd Edition" width="131" height="160" /></a><p class="wp-caption-text">Code Complete 2nd Edition</p></div>
<p style="text-align: left;"><strong>Code Complete 2nd Edition</strong>, by <a title="SteveMcConnell.com" href="http://www.stevemcconnell.com/" target="_blank">Steve McConnel</a> should be recommended reading on software engineering degrees at Universities the world over. It is a classic book about the software industry. McConnel makes the distinction between average programmers, who are happy to go through the motions of churning out (usually terrible) code and collecting their wages; and above average programmers, who continually seek to improve their base knowledge, actively improving their skills, who write solid, well designed and easily maintainable code. I think this was the book that really changed my mindset about being a programmer, about being proud of the work I do and the programs I write and maintain.</p>
<p style="text-align: left;">
<p style="text-align: left;">
<p style="text-align: left;">
<div id="attachment_103" class="wp-caption alignright" style="width: 131px"><a href="http://www.amazon.co.uk/gp/product/0131177052?ie=UTF8&amp;tag=tempocohes-21&amp;linkCode=as2&amp;camp=1634&amp;creative=6738&amp;creativeASIN=0131177052"><img class="size-full wp-image-103  " title="Working Effectively with Legacy Code" src="http://temporalcohesion.co.uk/wp-content/uploads/2009/10/51TG9F1B8AL._SL160_.jpg" alt="Working Effectively with Legacy Code" width="121" height="160" /></a><p class="wp-caption-text">Working Effectively with Legacy Code</p></div>
<p style="text-align: left;"><strong>Working Effectively with Legacy Code</strong>, by <a title="MichaelFeathers.com" href="http://www.michaelfeathers.com/" target="_blank">Michael Feathers</a> is another classic book, and another which I believe should be recommended reading on all University software engineering degrees. The reason I would recommended this book to any aspiring developer is that, more than likely they are going to be working with legacy code. I would say that 95% of the code I work with on a daily basis is legacy code, although that figure is slowly improving, thanks in a large part to the skills and knowledge I&#8217;ve gained from this book.  Feathers&#8217; defines legacy code as that which does not have unit tests. I would also add that most legacy code is often poorly designed, with no comments and is usually incredibly difficult to maintain. The book is split into three parts, the first part being about how you can bring about change in your legacy code base (and legacy developers!); the second part is like an FAQ, which links techniques together in a way to address common problems; the third part is a reference of the different dependency breaking techniques that can be employed to get your legacy code under test and under control.</p>
<p style="text-align: left;">
<p style="text-align: left;">
<div id="attachment_104" class="wp-caption alignleft" style="width: 138px"><a href="http://www.amazon.co.uk/gp/product/1933988274?ie=UTF8&amp;tag=tempocohes-21&amp;linkCode=as2&amp;camp=1634&amp;creative=6738&amp;creativeASIN=1933988274"><img class="size-full wp-image-104  " title="The Art of Unit Testing" src="http://temporalcohesion.co.uk/wp-content/uploads/2009/10/51PwNFas0pL._SL160_.jpg" alt="The Art of Unit Testing" width="128" height="160" /></a><p class="wp-caption-text">The Art of Unit Testing</p></div>
<p style="text-align: left;"><strong>The Art of Unit Testing</strong>, by <a title="ISerializable - Roy Osherove's Blog" href="http://weblogs.asp.net/ROsherove/" target="_blank">Roy Osherove</a>, is an excellent book, full of practical advice about unit testing. The book covers everything, from why you want to unit test your code, to how you can unit test code. Even if, as I had, you have written unit tests before, then you can still learn something from this book. Indeed there were several patterns on how to approach particular problems that I&#8217;d not even considered before. Also, I had never really gotten my head around using a mock object framework as part of my unit tests, but this book explains and demonstrates in a clear and concise manner, exactly how you can leverage your mock object framework of choice for your benefit. One minor criticism that I have though, is that I feel there is a certain element of bias toward <a title="Typemock Isolator, mock object framework" href="http://learn.typemock.com/" target="_blank">Typemock Isolator</a> &#8211; Osherove is a chief architect at Typemock.</p>
<p style="text-align: left;">
<p style="text-align: left;">
<div id="attachment_109" class="wp-caption alignright" style="width: 128px"><a href="http://www.amazon.co.uk/gp/product/159059388X?ie=UTF8&amp;tag=tempocohes-21&amp;linkCode=as2&amp;camp=1634&amp;creative=6738&amp;creativeASIN=159059388X"><img class="size-full wp-image-109  " title="Holub on Patterns" src="http://temporalcohesion.co.uk/wp-content/uploads/2009/10/51DbmGYuYuL._SL160_.jpg" alt="Holub on Patterns" width="118" height="160" /></a><p class="wp-caption-text">Holub on Patterns</p></div>
<p><strong>Holub on Patterns</strong>, by <a title="Holub.com" href="http://www.holub.com/" target="_blank">Allen Holub</a>, is another excellent book, about software design.  Design patterns offer an excellent way of not re-inventing the wheel, and Holub offers an entertaining and insightful tour of the majority of the <a title="The Famous Gang of Four book" href="href=&quot;http://www.amazon.co.uk/gp/product/0201633612?ie=UTF8&amp;tag=tempocohes-21&amp;linkCode=as2&amp;camp=1634&amp;creative=6738&amp;creativeASIN=0201633612&quot;" target="_blank">Gang of Four</a> patterns, and offers real world scenarios in which you would use them. The book is very opinionated, but this is not a bad thing, indeed it is refreshing to read as Holub is obviously very passionate about the subject. It certainly opened my eyes into the world of design patterns, as I&#8217;m one of these who finds concrete, interesting examples an excellent tool for learning, and I&#8217;ve always found the Gang of Four book rather dry.</p>
<div id="attachment_114" class="wp-caption alignleft" style="width: 138px"><a href="http://www.amazon.co.uk/gp/product/1933988363?ie=UTF8&amp;tag=tempocohes-21&amp;linkCode=as2&amp;camp=1634&amp;creative=6738&amp;creativeASIN=1933988363"><img class="size-full wp-image-114  " title="C# in Depth" src="http://temporalcohesion.co.uk/wp-content/uploads/2009/10/41-I8sBZWSL._SL160_.jpg" alt="C# in Depth" width="128" height="160" /></a><p class="wp-caption-text">C# in Depth</p></div>
<p><strong>C# In Depth</strong>, by <a title="Jon Skeet's Coding Blog" href="http://msmvps.com/blogs/jon_skeet/default.aspx" target="_blank">Jon Skeet</a> is an excellent book about the C# programming language. If you want to understand something about C#, and I mean really, truly understand why the language does what it does, then I suggest that you read this book. The book is clear and straightforward, with excellent examples. Honestly if most of the people posting C# questions on stackoverflow.com read this book, then I suspect the number of questions would stop increasing at the current rate.</p><img src="http://feeds.feedburner.com/~r/co/temporalcohesion/~4/BOjpMcYmu8M" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://temporalcohesion.co.uk/2009/10/17/my-recommended-reading-list/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://temporalcohesion.co.uk/2009/10/17/my-recommended-reading-list/</feedburner:origLink></item>
	</channel>
</rss>
