Archive

Archive for the ‘Uncategorized’ Category

Using Fluent Interfaces

February 6th, 2009

A couple weeks ago I was mentioning a training I did at Concentra. Well here’s the codebase that came out of the three days of training.

You’ll need a subversion client to checkout the code (like tortoiseSVN)

http://sleepoverrated.googlecode.com/svn/2009-01-14-Training_Codebase

Fluent Interfaces

Fluent Interfaces are are a way of writing code in which its more readable. Wikipedia uses the example of having a method return its class so you can add up a series of method calls like this.

new ConfigurationFluent().SetColor("blue")
                                           .SetHeight(1)
                                           .SetLength(2)
                                           .SetDepth(3);

The preparation exercise was to create a Movie Library that allowed us to search and sort in an number of different ways. We used the specification pattern to search thru an in memory collection. For searching moved towards a way of having a Linq like query syntax that let us select all the movies of different criteria. You can see some examples of this used in MovieLibrary.cs

Here is an example of how we used Movie.is_of_genre to search for all the action movies in our library. The Search Criteria is built up as a Specification and then checked for each movie in all_movies() by satisfied_by()

        public IEnumerable<movie> all_action_movies()
        {
            return all_movies().satisfied_by(Movie.is_of_genre(Genre.action));
        }

Looking at Move.is_of_genre() in Movie.cs we can see the Fluent Interface we created for created a Specification to check if a Movie has a genre that we specify.

        public static ISpecification<movie> is_of_genre(Genre genre)
        {
            return Where<movie>.has(x => x.genre).equal_to(genre);
        }

this is our fluent interface that we developed for querying. I recommend you look thru the code for this.

How would you write this?

When writing Fluent Interfaces you want to just write some code to do the thing you want to do in the way you want it to look. Then you have to figure out some way to make it compile. You may have to change your code around to get it to work.

Implement classes in reverse

You may naturally feel like implementing the Where class first but the one thing you know is what has to be returned and that is the responsibility of the last method.

  1. equal_to needs to return an ISpecification<movie>
  2. Where.has() needs to return a class with an equal_to method

We named the class returned by Where.has() as SpecificationBuilder<T,TOutput>. The x=> x.genre is passed into the new SpecificationBuilder in the constructor as a Func<T,TOutput> property_accessor. This Func is a function we call that takes in a Movie and returns a Genre if it was a delegate it would look like

        public Genre property_accessor(Movie movie)
        {
            return movie.genre;
        }

The great thing with C# generics is that it actually infers the TOutput type of genre in from the lambda x => x.genre. I barely noticed this ability until I started using Generics in Java. It is easier to just do this in Linq and there are some examples of that in MovieLibrary.cs but it’s a challenging exercise to try.

Doing things differently teaches you different things.

Uncategorized

Getting started with Boodhoo BDD

January 28th, 2009

Boodhoo BDD is a set of libraries that abstracts Rhino Mocks and MBUnit to give you an easy way to write BDD Specifications (a readable form of unit tests).

I’ve been using JP Boodhoo’s BDD helper libraries on a few projects and I’ve seen my tests become documentation because they’re more readable. I’ve been using it to set up our development team with application modules in a design by contract methodology. Which means that tests are in place first to provide a high level contract of the inputs and outputs of the class.

I’ll be covering this again in a grok talk tonight at the LDNUG but consider this a thorough transcript.

Definitions

  1. BDD – Behaviour Driven Development
  2. AAA – Arrange-Act-Assert syntax testing
    Here’s all the components you need to start developing using Boodhoo BDD.

jpboodhoo.bdd

helper libraries which give you a fluent interface to rhino mocks and mbunit so your interaction with these frameworks are abstracted away and readable.

you’ll need the following references to take full advantage of all the extension methods and reporting functionality of bdd doc.

jpboodhoo.bdd.dll
jpboodhoo.commons.core.infrastructure.dll
bdddoc.core.dll

checkout the latest version from http://subversion.assembla.com/svn/jpboodhoo_bdd with a subversion client like tortoisesvn

or you can download a build from here

here’s all the using statements you’ll need

using bdddoc.core;
using jpboodhoo.bdd;
using jpboodhoo.bdd.concerns;
using jpboodhoo.bdd.contexts;
using jpboodhoo.bdd.core;

first we need to setup all the concerns for our movie repository, this is where we would setup and dependancies and override the MovieRepository constructor if is need to inject anything.

public abstract class concern_for_movie_repository : observations_for_a_sut_with_a_contract
    {
    }

and the specification looks like this

    [Concern(typeof (MovieRepository))]
    public class when_all_movies_are_asked_for : concern_for_movie_repository
    {
        static IEnumerable results;

        static concern c = () => {};	

        static because b = () => results = sut.All();                                

        [Observation]
        public void should_find_a_movie()
        {
            results.Count().should_not_be_equal_to(0);
        }
    }

the main points are

  1. Concern is a MBUnit TestFixture
  2. Observation is a MBUnit Test
  3. sut is a MovieRepository which is created in observations_for_a_sut_with_a_contract based on the Generic type.
  4. concern,because and any fields need to be static
  5. a concern in concern_for_movie_repository will run before the concern in when_all_movies_are_asked_for

Here’s some more thorough examples to get you started

  • Test examples with MBUnit and jpboodhoo.bdd
  • How I’m Currently Writing My BDD Style Tests – Part 1
  • How I’m Currently Writing My BDD Style Tests – Part 2

    AutoHotKey BDD naming

    A script for AutoHotKey which replaces the spaces you type with underscores so you can quickly describe your behaviours in a underscore naming convention. You use Ctrl-Shift U to turn this off and on and there’s a tray icon to tell you if its on or off.

    After you download the

    BDD Doc

    BDD Doc is the report generator of this package. It uses the Concern and Observation attributes that we used above and generates an html report to show you which Concerns are behaviours of which Objects.

    If you have an MBunit test report you can include the results in the BDD Doc report too.

    you can checkout bdd doc here with a subversion client

    http://svn2.assembla.com/svn/bdddoc

    or download a build here

    Here’s how you call BDD Doc at command line.

    bdddoc.console.exe tests.dll TestAttribute SpecReport.html test.report.xml

    and here’s what the SpecReport.html report will look like

    bdddoc_report

    Resharper Templates

    File Templates are Live Templates allow you to insert new files and do code insertion with aliases. Its not needed but its definitely useful for developing faster.

    download live templates

    you can import the live templates by going to Resharper > Live Templates and clicking on the import button below.

    bdd-livetemplates01

    Welcome to a world with readable code.

  • Uncategorized

    First training course of the year

    January 16th, 2009

    borough market

    Last week I taught my first course of the year for Concentra. I have heard some horror stories about running internal training courses but I really enjoyed it. It’s definetly a cool place to work, there’s some smart people there.

    I used an evolutionary teaching style where we started writing raw C# code without LINQ and moved towards third party libraries like log4net, NHibernate and ASP.Net MVC. There was just too much to cover and really It should’ve been the original 5 day course I had planned.

    I find that teaching really makes you need to know what your talking about. Most of the time you are not writing infrastructure code and to be able to start an app from scratch lets you reassess how you do things.  I have a big crush on Iteration 0 efficiency there’s so much to setup and if you start into app code prematurely you end up working with a handicap.

    Here’s the outline of what we managed to cover, I will be posting code shortly.

    Day 1

    • Refactoring
    • TDD
    • BDD
    • Team System
    • IComparer<T>
    • Paired Programming
    • Delegates
    • Predicate<T>
    • Specification Pattern
    • Strategy Pattern
    • Lambdas
    • Searching and Sorting on Collections
    • Fluent APIs
    • Rich Domain Model
    • Barebones Data Access

    Day 2

    • Refactoring Data Access
    • Factory Pattern
    • DBProviderFactory
    • log4net
    • Service Layer Pattern
    • Mapper Pattern
    • Repository Pattern
    • NHibernate
    • Detached Criteria

    Day 3

    • ASP.Net MVC
    • JQuery
    • AJAX calls with JQuery
    • Scrum
    • User Stories
    • Kanban
    • Dependency Injection
    • Rhino Mocks

    Uncategorized

    How Did I Get Started In Software Development?

    July 15th, 2008

    JP asked me to to post how I got start in software, so if you want to know my favourite colour or whatever that’ll have to be another post.

    How old were you when you first started in programming?

    I’m not too sure but I must have been about 8 or 9 years old. I probably would have done it earlier if I had a computer with basic on it. The one thing that was worse than having a computer that took cassette tapes was having a broken play button on the cassette deck.

    What was your first programming language?

    Our Neighbour had a Apple II and I would be over there playing games all the time. One day we found a book for Apple Basic and it had a cool looking game in it so I proceeded to type out all the sample code they had for it so I could play it. It never worked but I soon followed that up with an application just as complex.

    10 PRINT "Something Funny in the 80s"
    20 GOTO 10
    RUN

    For some reason the next language I learned was Motorola 86000 Assembly.

    What was the first real program you wrote?

    The first real program I wrote in school was a hockey pool program. It was a team project and I was doing the UI. Everyone else was doing text only apps on the mac but I managed to add menus and normal GUI stuff and the best part was if you tried adding a menuitem outside of the menu array it completely destroyed the computer. Who would have known that you’d need to reinstall your OS from a bad line of code you wrote.

    What languages have you used since you started programming?

    In order of apperance
    Basic,Turbo Pascal,C++,Perl,Modula-2,Visual Basic,PHP,Java,ColdFusion,C#,VB.Net,Ada,Python

    I also did assemble for a bunch of different platforms
    Assembly for 86000,PIC 16F84,Z80,Allen Bradely PLC5, Motorola 68HC11, C/ASM on TI C67x DSP

    What was your first professional programming gig?

    At a company called IQLinux.com, we were making the Ebay of Services. It sounded great but we ended up suffering from Feature Creep so much that the site got way too complex. We were working out how to do dispute arbitration before we even had users. I ended up sticking around to the point where we had moved into the basement of the founders mothers house. I still work with one of my colleuges on another project.

    If you knew then what you know now, would you have started programming?

    Of course, if I didn’t enjoy what I was doing I’d do something else. I started out in Electrical Engineering but realized that product development was way too complex and software allowed you to do new things really quickly. I guess I just want to be able to make an impact on the world around me and I didn’t see that happening in hardware.

    If there is one thing you learned along the way that you would tell new developers, what would it be?

    People skills are equally as important as technical skills. Just because someone has been in the industry for 10 years doesn’t mean he’s got any experience. He may just had 1 years experience 10 times. Your education doesn’t stop when you graduate, thats when it begins. If your lucky your university actually taught you about software engineering, my university did not and I was in a software engineering program.

    What’s the most fun you’ve ever had programming?

    Working for a startup, It’s very cool to start out without the years of management overhead that you get at a large company. Too much freedom can kill you but It’s nice to be able to see what isn’t working and be able to change it. I love being given broad requirements and coming up with the solution to achieve them. It defers a lot from consulting gigs where you show up and everything is mostly planned out and you just have to implement.

    Who am I calling out?

    Micheal Foord
    Ben Hall
    Zi Makki
    Andrew Myhre

    Uncategorized

    [Guerilla Development] Setup Source Control in 60 seconds

    April 6th, 2008

    Have you ever had a job where they don’t have source control? There may be some good excuses but you’re still missing one of best tools you can have. Today I’ll show you how to setup source control in under a minute without a server.

    It can be daunting looking at Subversion when you think that you need to setup a server with it but thats not the case. You can use TortoiseSVN to create a server-less repository. I don’t recommend this setup but it gives a way to try out Subversion or a quick way of setting up a source control system. The best thing about this is that you can copy the repository to a full subversion server when you have one. If you like using subversion I recommend Visual SVN Server on windows.

    Reasons to use this setup

    1. You want to try out subversion.
    2. You want source control but don’t have the time to set it up.
    3. You do all your work disconnected.

    Reasons to use a server instead

    1. You will probably run into problems when two people are trying to checkin files at the same time.
    2. You want to remotely access the source control.

    How To Setup

    Here’s how you can use TortoiseSVN to create a repository without a server.

    1. Download and install TortoiseSVN
    2. Create a directory for all your repositories (I called mine c:\repositories)
    3. Create a directory for this repository (I called mine sample)
    4. Create your first repository (by going into the sample dir and right click)

    create repository

    5. Use a FSFS file system (its just a recommendation)

    create repository

    6. You should see some folders (conf,dav,db,hooks,locks)

    subversion folders

    7. Create a network share folder (right click on c:\repositories)
    creating network share

    8. Make sure the share has write access

    setting write access

    9. Checkout the repository to another directory (right click on any dir)

    checkout

    10. Fill in “Url of repository”  (the url to a network share which looks like this file:////computername/repos)
    11. Fill in the checkout directory  (the dir doesn’t have to exist yet it will ask if it should create it for you)

    checkout directory

    Summary

    You now know how to setup subversion on your local file system. TortoiseSVN commands can be found in the right click context where you found the Checkout and Create Repository here options, just make sure you are click in or on the folder you checked out. Here’s some links that will help you get started.

    Technorati tags

    Uncategorized

    [Build Knowledge] Promoting your build

    December 5th, 2007

    If there’s one thing that you should ask your self across everything you do it’s “How can we test this”. Deployments are often overlooked as so infrequent that it doesn’t need to be fully tested or automated. I’ll show you how to setup a simple promotion system using CruiseControl.Net and NAnt.

    Here are the symtoms that you need to improve how your deploying your applications.

    1. You can’t remember if you deployed some fix or feature and have to check to see if you did.
    2. You don’t remember when you actually deployed but remember it was around march last year.
    3. You’re the only person that knows how to deploy.
    4. You’ve accidently deployed a the application built in debug.

    What you’ll need

    1. Download and install CruiseControl.Net
    2. Read thru the last article where we covered versioning with NAnt and CruiseControl.Net

    You can download the code from google code at

    http://sleepoverrated.googlecode.com/svn/

    If you have a Subversion Client like TortoiseSVN then you can just check out all the code.

    The Enviroments

    Enviroments

    We’ll be using three server enviroments here, each one could be a web server or a windows form or anything but today it’ll just be a command line application. The Application prints its version number and the enviroment name from a config file. Hopefully after we’re thru here you can scale this system out to whatever your needs are.

    NAnt Configuration

    We will need two builds one for Current (our Continuous Integration) and one for Development. The only difference is that Current is compiled in debug and development is compiled in release mode. Its good practise to start compiling in debug on your Continuous Integration enviroment so that you can generate Code Coverage reports using NCover.

    The only promotion we’re showing here is for staging since you should really seperate your promotion to live into another process to prevent accidental promotions.

    buildknowledge.build

    This is a variation of the last articles build file.

    The main differences are:

    1. There’s a debug property so we can set the compile mode
    2. the expand.template.file lets us generate a config file by replacing tokens in config\app.config.template
    3. deploy.copy lets us copy a whole directory of development to staging
    4. include buildfile lets us add more tasks specific to our different enviroments in the second build file

    The actually targets we’ll be running are in the next NAnt file so these are just lower level tasks

    <?xml version="1.0" encoding="utf-8"?>
    <!--EXTERNAL_PROPERTIES: target.dir;source.dir;AppConfig.EnviromentName;AppConfig.Directory-->
    <project name="BuildKnowledge" default="current">	
    
    	<!-- add tasks in from the enviroments build file -->
    	<include buildfile="buildknowledge.enviroments.build"/>
    
    	<!-- initialize properties -->
    	<property name="debug" value="false" />
    	<property name="target.dir" value="build" />
    	<property name="source.dir" value="" />
    
    	<target name="init" description="clean out build dirs">
    		<delete dir="build" />
    		<mkdir dir="build" />
    		<delete dir="${target.dir}" />
    		<mkdir dir="${target.dir}" />
    	</target>
    
    	<target name="asminfo" description="generating the AssemblyInfo.cs">
    		<if test="${property::exists('CCNetLabel') == false}">
    			<property name="CCNetLabel" value="0.0.0.1" />
    		</if>
    
    		<asminfo output="build\AssemblyInfo.cs" language="CSharp">
    		    <imports>
    		        <import namespace="System" />
    		        <import namespace="System.Reflection" />
    				<import namespace="System.EnterpriseServices" />
    		        <import namespace="System.Runtime.InteropServices" />
    		    </imports>
    		    <attributes>
    		        <attribute type="ComVisibleAttribute" value="false" />
    		        <attribute type="CLSCompliantAttribute" value="true" />
    		        <attribute type="AssemblyVersionAttribute" value="${CCNetLabel}" />
    		        <attribute type="AssemblyTitleAttribute" value="Build knowledge - Hello World" />
    		        <attribute type="ApplicationNameAttribute" value="BuildKnowledge" />
    		    </attributes>
    		    <references>
    		        <include name="System.EnterpriseServices.dll" />
    		    </references>
    		</asminfo>
    	</target>
    
    	<target name="compile" depends="init,asminfo" description="compiling all the code in the src dir">
    		<csc output="${target.dir}\${project::get-name()}.exe" target="exe" debug="${debug}">
    			<sources basedir="src">
    				<include name="**/*.cs" />
    				<include name="../build/AssemblyInfo.cs" />
    				<exclude name="**/AssemblyInfo.cs" />
    			</sources>
    		</csc>
    	</target>
    
    	<target name="deploy.copy" description="copy promotion of one build to the next enviroment">
    		<if test="${directory::exists(target.dir) == false}">
    			<mkdir dir="${target.dir}" />
    		</if>
    		<copy todir="${target.dir}" overwrite="true">
    			<fileset basedir="${source.dir}">
    				<include name="**/*" />
    				<exclude name="*.config" />
    			</fileset>
    		</copy>
    	</target>
    
    	<target name="load.settings" description="load all the enviroment settings">
    	    <if test="${file::exists('config\' + properties)}">
    	      <echo message="Loading ${properties}" />
    	      <include buildfile="config\${properties}" />
    	    </if>
    	</target>
    
    	<target name="expand.template.file" description="replace the tokens in the template file">
    		<copy file="config\${target}.template" tofile="config\${target}" overwrite="true" >
    			<filterchain>
    				<replacetokens>
    					<token key="AppConfig.EnviromentName" value="${AppConfig.EnviromentName}" />
    				</replacetokens>
    			</filterchain>
    		</copy>
    	</target>
    
    	<target name="deploy.config" description="create the config file and deploy it">
    		<property name="target" value="app.config" />
    		<call target="expand.template.file" />
    		<copy file="config\${target}" tofile="${AppConfig.Directory}\${project::get-name()}.exe.config" />
    	</target>
    </project>

    buildknowledge.enviroments.build

    Here’s our enviroments, each one will used by CruiseControl.Net as a different project. We have a file for each enviroment with all the settings we’ll be using. This lets you quickly change the connectionstring but today all we’re using it for is the the name of the Enviroment and its directory.

    1. Current – debug compile, generate config
    2. Development – release compile, generate config
    3. Staging – copy development, generate config
    <?xml version="1.0" encoding="utf-8"?>
    <project name="BuildKnowledgeEnviroments">	
    
    	<target name="current" description="starting Continous Integration build">
    		<property name="properties" value="current.enviroment.xml" />
    		<call target ="load.settings" />
    
    		<property name="debug" value="true" />
    		<property name="target.dir" value="${AppConfig.Directory}" />
    		<call target="compile" />
    
    		<call target="deploy.config" />
    	</target>
    
    	<target name="development" description="starting Development build">
    	    <property name="properties" value="development.enviroment.xml" />
    		<call target="load.settings" />
    
    		<property name="debug" value="false" />
    		<property name="target.dir" value="${AppConfig.Directory}" />
    		<call target="compile" />
    
    		<call target="deploy.config" />
    	</target>
    
    	<target name="staging" description="starting Staging promotion">
    	    <property name="properties" value="development.enviroment.xml" />
    		<call target="load.settings" />
    		<property name="source.dir" value="${AppConfig.Directory}" />
    
    	    <property name="properties" value="staging.enviroment.xml" />
    		<call target ="load.settings" />
    		<property name="target.dir" value="${AppConfig.Directory}" />
    
    		<call target="deploy.copy" />
    
    		<call target="deploy.config" />
    	</target>
    </project>
    
    

    app.config.template

    This is where we’re generating out app.config from, the @AppConfig.EnviromentName@ is the token that we’re looking for in the expand.template.file task.

    <?xml version="1.0"?>
    <configuration>
    	<appSettings>
    		<add key="EnviromentName" value="@AppConfig.EnviromentName@"/>
    	</appSettings>
    </configuration>

    development.enviroment.xml

    With the load.settings task we load in our enviroment settings files here’s the one for the development enviroment. It gives us the properties ${AppConfig.EnviromentName} and ${AppConfig.Directory} which you’ll see being used in the NAnt files.

    <?xml version="1.0"?>
    <properties>
    	<property name="AppConfig.EnviromentName" value="Development" />
    	<property name="AppConfig.Directory" value="deploy\development" />
    </properties>
    

    CruiseControl.Net Configuration

    The next step is in the ccnet.config we have a different project for each enviroment and the things to notice here are

    1. Both Development and Staging are using the Remote Project Labeller to take the version number from the previous build enviroment. So Development uses Currents version number and Staging uses Developments version number. We use some trickery here because actually its still a local project but its using the tcp connection to talk to itself.
    2. Each project is using the same build file but its pointing at a different target from our enviroments file.
    <cruisecontrol>
    	<project name="BuildKnowledge Current">
    		<tasks>
    			<nant>
    			  <executable>C:\code\sleepoverrated\02_Build_Knowledge-Promoting_Builds\tools\nant\bin\NAnt.exe</executable>
    			  <baseDirectory>C:\code\sleepoverrated\02_Build_Knowledge-Promoting_Builds</baseDirectory>
    			  <nologo>false</nologo>
    			  <buildFile>buildknowledge.build</buildFile>
    			  <targetList>
    			    <target>current</target>
    			  </targetList>
    			  <buildTimeoutSeconds>1200</buildTimeoutSeconds>
    			</nant>
    		</tasks>
    		<labeller type="iterationlabeller">
    		    <prefix>1.0</prefix>
    		    <duration>2</duration>
    		    <releaseStartDate>2007/11/24</releaseStartDate>
    		    <separator>.</separator>
    		</labeller>
    	</project>
    
    	<project name="BuildKnowledge Development">
    		<tasks>
    			<nant>
    			  <executable>C:\code\sleepoverrated\02_Build_Knowledge-Promoting_Builds\tools\nant\bin\NAnt.exe</executable>
    			  <baseDirectory>C:\code\sleepoverrated\02_Build_Knowledge-Promoting_Builds</baseDirectory>
    			  <nologo>false</nologo>
    			  <buildFile>buildknowledge.build</buildFile>
    			  <targetList>
    			    <target>development</target>
    			  </targetList>
    			  <buildTimeoutSeconds>1200</buildTimeoutSeconds>
    			</nant>
    		</tasks>
    		<labeller type="remoteProjectLabeller">
    			<project>BuildKnowledge Current</project>
    			<serverUri>tcp://localhost:21234/CruiseManager.rem</serverUri>
    		</labeller>
    	</project>	
    
    	<project name="BuildKnowledge Staging">
    		<tasks>
    			<nant>
    			  <executable>C:\code\sleepoverrated\02_Build_Knowledge-Promoting_Builds\tools\nant\bin\NAnt.exe</executable>
    			  <baseDirectory>C:\code\sleepoverrated\02_Build_Knowledge-Promoting_Builds</baseDirectory>
    			  <nologo>false</nologo>
    			  <buildFile>buildknowledge.build</buildFile>
    			  <targetList>
    			    <target>staging</target>
    			  </targetList>
    			  <buildTimeoutSeconds>1200</buildTimeoutSeconds>
    			</nant>
    		</tasks>
    		<labeller type="remoteProjectLabeller">
    			<project>BuildKnowledge Development</project>
    			<serverUri>tcp://localhost:21234/CruiseManager.rem</serverUri>
    		</labeller>
    	</project>
    </cruisecontrol>
    
    

    See it in action

    Now lets see how well this works when we’re actually using it.

    Building Current

    since we’re not using the sourcecontrol block in CruiseControl.Net we’ll have to forcebuild the Current project but you should set it up to build everytime you check something in.

    So select Current and start a force build and the version numbers start to increase just like last time.

    CCTray

    Checking the directory deploy\current you can see the new files we just generated. You’ll notice that here we have a pdb file because we compiled in debug.

    build output files

    Now if we run this build we can see that its got the correct version number and its using the correct configuration file that we generated.

    version number

    Building Development

    Now when we do a force build on Development we build a new release from code. If we were under source control it would be the latest version so there is the possibility of building while the code is being updated. If that happens you could always just rebuild development again. You could use the modificationDelaySeconds element on the project block in ccnet.config to setup a delay on building.

    cctray

    If we look in the deploy\development directory we can quickly see that we’ve built in release mode because we’re missing the pdb.

    files for release

    Running the app we can see that its using the right configuration file.

    development running

    Building Staging

    Finally we do a force build on staging and that will copy over the last build of development and generate the config file. There’s also been some builds on Current but that won’t affect our promotion to staging. Another thing to notice is that you have the Last Build Time to quickly check the last time you deployed to staging. If you use the CruiseControl.Net web dashboard you can even see the log of all the promotions you’ve done, that way you never need to wonder what versions where or if someone did a promotion while you were off sick.

    CCTray last time

    Running the app we can see that its using the right configuration file.

    running on staging

    Uncategorized

    [DDD6] Introduction to Silverlight 1.1 with Chris Hay

    November 25th, 2007

    Chris Hay

    Interactions (using c# behind XAML) are new to 1.1
    windows mobile will be supported in the future (here’s hoping android too)
    Silverlight 1.1 will hopefully ship in summer 2008
    1.1 doesn’t work with Visual Studio 2008 RTM so use Beta2 until the upcoming Silverlight 1.1 CTP refresh
    “Add Silverlight Link” on a web site doesn’t copy silverlight.js into your project
    you can’t edit and continue with a silverlight project you have to recompile
    There’s no Global styling yet
    lots of XAML demos
    TransformGroup allows you to do multiple transforms
    can’t group shapes like WPF so you have to stick your shapes in a canvas instead
    no content support like WPF yet
    blend 1.0 is for WPF only so use the blend beta instead
    Silverlight Pad
    there’s no 3D acceleration with silverlight so you can work with multiple platforms (why not use an OpenGL wrapper on *nix)
    all 3D is run off CPU power

    Demos sounds (I was just telling a friend how embedded midi was going to make a come back)

    Thanks Chris I didn’t have many notes on this one since there were a lot of XAML demos, too bad I missed the second session.

    Uncategorized

    [DDD6] Why IronRuby? with Dave Verwer

    November 25th, 2007

    Dave Verwer

    Ruby had the first beta in 1995

    Iron Ruby is branched from 1.8.x branch of ruby modulo
    DLR is just a layer on top of the CLR, still compules to IL
    IronRuby is a blind implementation for clean IP
    ruby bridge by john lam was an early use of the CLR in Ruby
    the DLR came out of IronPython work
    IronRuby has two developers working on it at microsoft
    rubyforge subversion repository is a mirror of  the internal microsoft codebase
    you can run regular ruby code in IronRuby

    Optional Punctuation
    semi colons, returns, braces, etc.
    you can determine which puntuation you need to make your code readable
    immutable string declarations are done like :init which is the string ”init”
    immutable strings are never disposed

    Syntactic sugar
    Optional Punctuation makes Domain Specific Languages more forgiving for syntax and easier to write
    Sigils prefixing variable names to add description
    Sigils include local, $global, @instance, @@class, Constant
    sigils determine scope and are optional
    ruby strongly typed but can redeclare vars
    shorthand Range.new(1,100) 0..100
    %w(words in an array) will create an array that is seperated by spaces
    using an immutable string as a hashtable key can cause collisions
    puts var unless x.nil?  this will handle null cases
    strings can be single or double quotes and nest the other type without using escape characters (when its mixed you need them though)
    theres no character type natively but you can use the .Net Char type
    big numbers can be assigned dynamically you don’t need to worry about exceeding the maximum value
    no native decimal type support but you can use the .net decimal type
    can alias methods on a class level so you don’t have to program in american

    blocks in ruby are lambda methods,anonymous delegates in c# and closures in js
    core language contruct – heavy use of delegates
    there are no for loops you just use the times block

    a for loop
    10.times do {print “Hello”}   this print Hello 10 times

    a foreach loop
    ["a","b"].each do |letter|
      puts letter
    end

    file.each_line do |line|
      line =~ /regex/
    end

    a try catch
    begin
      …
    ensure
      …
    end

    yield keyword exists like c#
    === is the match operator and compares as well as it can

    mixed matching in case statements
    case i
      when MyClass
        …
      when 1..100
        …
      when /^[a-z]*$/
        …
    end

    Mixins
    like c# extension methods
    String.module_eval do

    you can redefine a class to override or add a mixin

      class String
        def capitalize_all
       …
     end
      end
     
      class String
        undef length
      end
      
    Linguistics library in ruby (blew my mind, not hard to do just nice to have done for you already)
     
    individually extend instances of objects

    in.extend(JPEGMethods)  

    class ReverseString
      def method_missing(method_name)
        …
      end
    end

    method_missing is used to do dynamic querying of database based on what the current class is and that its trying to do a find
     
    customer.find_by_email_or_name

    this makes intellisense a hard problem
    naming is underscore seperated and lowercase
    name mangling allows the CLR namespaces to be available with Ruby naming conventions

    Thanks Dave

    Uncategorized

    [Build Knowledge] Versioning

    November 17th, 2007

    Today I’ll show you how to use NAnt and Cruise Control.Net to Version your application.

    What you’ll need

    1. NAnt A .Net Build tool. We’re going to use this to compile our Hello World Application and set the version number.
    2. Cruise Control.Net A Continious Integration Server that lets us start NAnt and makes our version number.

    Our Application

    Theres nothing much to our application it just shows the Assembly Version at command line.

    using System;
    using System.Reflection;
    
    namespace BuildKnowledge.CmdLine
    {
        class Program
        {
            static void Main(string[] args)
            {
                Console.Out.WriteLine("Hello World v" + Assembly.GetExecutingAssembly().GetName(false).Version);
            }
        }
    }
    

    NAnt Build file

    Lets look at the build file

    <?xml version="1.0" encoding="utf-8"?>
    <project name="BuildKnowledge" default="compile">
    	<target name="init">
    		<delete dir="build" />
    		<mkdir dir="build" />
    	</target>
    
    	<target name="asminfo">
    		<if test="${property::exists('CCNetLabel') == false}">
    			<property name="CCNetLabel" value="1.0.0.1" />
    		</if>
    
    		<asminfo output="build\AssemblyInfo.cs" language="CSharp">
    		    <imports>
    		        <import namespace="System" />
    		        <import namespace="System.Reflection" />
    				<import namespace="System.EnterpriseServices" />
    		        <import namespace="System.Runtime.InteropServices" />
    		    </imports>
    		    <attributes>
    		        <attribute type="ComVisibleAttribute" value="false" />
    		        <attribute type="CLSCompliantAttribute" value="true" />
    		        <attribute type="AssemblyVersionAttribute" value="${CCNetLabel}" />
    		        <attribute type="AssemblyTitleAttribute" value="Build knowledge - Hello World" />
    		        <attribute type="ApplicationNameAttribute" value="BuildKnowledge" />
    		    </attributes>
    		    <references>
    		        <include name="System.EnterpriseServices.dll" />
    		    </references>
    		</asminfo>
    	</target>
    
    	<target name="compile" depends="init,asminfo">
    		<csc output="build\${project::get-name()}.exe" target="exe" debug="false">
    			<sources basedir="src">
    				<include name="**/*.cs" />
    				<include name="../build/AssemblyInfo.cs" />
    				<exclude name="**/AssemblyInfo.cs" />
    			</sources>
    		</csc>
    	</target>
    </project>
    

    This is the BuildKnowledge.build file that will run our build. Here’s the steps we’re taking

    • [init] Create a directory called build
    • [asminfo] Generate the AssemblyInfo.cs
    • [compile] Compile BuildKnowledge.exe

    The important thing to see is CCNetLabel which is a property that CCNet is going to send down to the NAnt task. This is called an Integration Property and there are additional properties for things like the build time just check the list.

    Cruise Control .Net Configuration

    Once you’ve installed cruise control you’ll want to update ccnet.config to add this project. You’ll need to update the nant task with the correct paths to where your files are located. In an actual setting we’d actually have a sourcecontrol block that automatically triggers the build and updates the working copy on the build server. For now we’ll just trigger the build manually which isn’t truely Continious Integration but it’ll work for this example. The Labeller Block is where we come up with the version number for the assembly and it will show up on Cruise Control.Net and it will be sent down to NAnt.

    <cruisecontrol>
    	<project name="BuildKnowledge Current">
    		<tasks>
    			<nant>
    			  <executable>C:\code\sleepoverrated\01_Build_Knowledge-Versioning\tools\nant\bin\NAnt.exe</executable>
    			  <baseDirectory>C:\code\sleepoverrated\01_Build_Knowledge-Versioning</baseDirectory>
    			  <nologo>false</nologo>
    			  <buildFile>buildknowledge.build</buildFile>
    			  <targetList>
    			    <target>compile</target>
    			  </targetList>
    			  <buildTimeoutSeconds>1200</buildTimeoutSeconds>
    			</nant>
    		</tasks>
    		<labeller type="iterationlabeller">
    		    <prefix>1.0</prefix>
    		    <duration>2</duration>
    		    <releaseStartDate>2007/11/24</releaseStartDate>
    		    <separator>.</separator>
    		</labeller>
    	</project>
    </cruisecontrol>
    

    The End Result

    Once you have everything setup you’ll need to

    1. Start up server\ccnet.exe to start CCNet in where you installed CCNet (or you can start the service).
    2. Install cctray\cctray.exe and add the BuildKnowledge Current project from your localhost.
    3. Force Build the project
    4. Run our BuildKnowledge.exe in the build folder

    version number

    Thats all you have to do to add version numbers I hope you’ve gotten something out of this, we’ll be coverring more advanced topics next time.

    BuildKnowledge01.zip (4 KB)

    Uncategorized

    Where’s all the posts?

    November 14th, 2007

    So I finally moved over to actually blogging software but you might be wonderring where all the posts went to. Don’t worry they’re still around and I’m still posting in there.

    Go checkout Sleepoverrated Stream via [Tumblr]

    You can currently see it in the right hand nav but its not that obvious so I’ll fix that in the upcoming site design.

    Uncategorized