Tuesday 23 August 2011

Evil Linq!

I love Linq. Most of the time it helps us do some clever stuff in an elegant, fluent way. Recently though, I have come to dread seeing certain kinds of Linq statements.

The biggest problem I have with Linq, is that it encourages you to write sloppy code, with no error handling at all. This is fine in theory as we 'should' just let exceptions propagate, but in the real world, where you have users editing the content, I have seen many a site go down because someone didn't check for null when getting something out of the repository.

The other issue with Linq is readability and a painful debugging experience. If you use ReSharper like me, you will often get suggestions to covert loops to Linq queries. Fine in theory, but if you have 3,4 or even 5 clauses to it, it quickly becomes painful to read. Combine this with the fact that you can't execute lambdas in the immediate window ( seriously Microsoft - wtf?) and you are in a world of hurt.

Linq makes stuff ugly sometimes, don't do everything resharper tells you kids!

Monday 22 August 2011

Hiring senior developers

Finding good developers is hard.

I don't know about the US, but there seems to be a genuine skills shortage in London. I have seen technical tests and interviewed literally hundreads of people over the last few years and only a handful were good enough for a job.

There were several people who passed the online technical test, but when faced with a technical phone interview, the large gaps in their knowledge quickly become apparent. Of the few that make it through to a face to face interview,  a lot seem to have, how shall I put it, poor communication skills. I'm not talking about the standard interview nerves everyone gets either. I am talking about a genuine inability to articulate them selves. If you can't speak technical to me, the chances of you explaining issues to a pm or client are minimal.

Harsh, but true.

Tuesday 24 May 2011

A Very Simple Hello World iphone app

So here is the simplest program you can create for an iphone using xcode (the IDE) and objective c. The all time classic that is hello world!

Step 1 - Download Xcode:

Go to the apple dev centre, register and download the latest version of xcode.

Step 2 - Open Xcode:

Launch Xcode, found under /Developer/Applications/. You will presented with a window like the one below. Select Create a new Xcode project.

Image and video hosting by TinyPic

Step 3 - Create the project:

The next window will present options for the various different types of projects you can create. Select "View based application". You will be prompted for a location to save the project and a name, call it "HelloWorld". Anywhere is fine, but I don't recommend putting it under the /Developer/ folder as apple have tendency to wipe that folder when you upgrade xcode.
Image and video hosting by TinyPic

Step 4 - Select the Simulator:

You should now have your "solution" open, with all the appropriate files pre-setup for you to launch your application in the simulator. Notice the drop down in the top left of the IDE, this lets you determine how you launch your app - via the simulator or onto your phone. Make sure Simulator is selected.

Image and video hosting by TinyPic


Step 5 - Open Interface Builder:

Ok, now we will actually modify our code to show "Hello world". If you look in the solution explorer ( on the left) and navigate to the /Resources/ folder. Double click on MainWindow.xib (pronounced nib files). This will launch a program called "Interface Builder". It should open at least 3 windows:

  1.  Library - a list of all components you can use on your interface
  2. Controller Window - The view which we will we modify - it represents the screen.
  3. Attributes Inspector Window- Used to alter properties of items on your interface ( fonts etc)
Select the Library and scroll down the list of components and select Label. Drag it onto the controller window like below. 

Image and video hosting by TinyPic

Click on the label that you have just dragged onto the controller. Select The Attributes Inspector Window and change the text property to "Hello World". Save the File by pressing cmd + s.



Step 6 - Launch Your App:

If we navigate back into Xcode and select the "build and run" option in the middle of the IDE, it will now launch your app in the simulator. If you select the breakpoints button ( just to the left), it will put you in debug mode and you can debug just like good old visual studio.

Image and video hosting by TinyPic

Ta, da! Hope someone finds that useful.

Sunday 1 May 2011

What makes a good agency developer?

Having worked at a couple of different agencies now, I thought I might share my opinion on what I look for when hiring developers. I generally look for a couple of different things:

  1. Self motivation 
  2. Communication Skills
  3. Understanding of the key principles (TDD, SOLID, DRY, KISS, Design Patterns)
Self Motivation


This is probably is most important requirement. As well all know, every few years, the whole industry landscape changes and if you are not prepared to keep learning, you may as well give up now.  If you are not motivated towards continual self improvement, you will always write the same old sloppy code, you will become bored and the amount of bugs you write is only going to increase.

Communication Skills *

Finding a committed and knowledgeable developer who can articulate them selves well, to project managers, client service and clients is hard, but vitally important. We all know the stereotype, but it can so often be true. In the old days, the developer would often just be given a big requirements document and locked in a room until it was done. The role of a developer has changed somewhat since the advent of agile methodologies though. It is all about constant feedback and refinement. If you can not sit in a planning meeting and help create the stories and acceptance criteria, your career progression will be limited. You will just be seen as an obstacle to the people you are trying help.

Understanding of the key principles

The most common misconception is that knowing the minutiae of some framework / language is the most important thing. It is perhaps the most irrelevant. I consider myself to be a reasonably competent developer ( I am sure some would disagree!), but I still continually have to look up things on a daily basis. It does not make me any less proficient. Perhaps 20 years ago before the emergence of every developers best friends, it was, but not any more.

Forget syntax, once you know the majority of the (current) principles and patterns, I know you will write good code. The last stage of the interview process where I am now requires you to take a small practical technical test. It will be a reasonably trivial problem to solve and there is no time limit. I don't care if you can not get it working completely. I'm more interested in how they started to abstract it and whether they wrote any tests.

* I am well aware that there are probably hundreds of grammatical errors in this post. I assure you, they are all deliberate.

Friday 29 April 2011

Covariance and contravariance in c-sharp 4

Wow. They are some scary fucking words. The brilliant Jon Skeet does a great job of describing what they are all about in his tekpub video, but you need to pay for access ( well worth doing btw). Im going to try my best to describe what they are and how they can be useful.

Normally when we declare an interface or a class, we would do something like this:

 interface IFoo <T> {  
    T GiveMeSomething()  
    void TakeSomething(T instance)   
 }  

This can provide us with restrictions though. Say we have the following class declarations:

 class Fruit { }  
 class Apple : Fruit {}  
 class Banana : Fruit {}  

One would expect that you could do something like this:

 List<Fruit> fruitBowl = new List<Fruit>();  
 fruitBowl.Add(new Apple());  

Obviously, we can not without casting it down to it's base type. The reason for this, is that we can read and write to the list. I could request an item for the list, but I don't really know what type it would be as I could add any type of fruit. This goes against the whole point of a strongly typed List. So naturally, we get a compile error.

Covariance is all to do with values coming out of an interface/class. Effectively making it read only.

 interface IFoo <out T> {  
    T GiveMeSomething()  
 }  

Covariance is effectively saying you can not modify this object, only take from it, hence the out parameter. The famous example being IEnumerbale<T>.

Contravariance is when values only go into a class/interface. Effectively making it write only.

 interface IFoo <in T> {  
    void TakeSomething(T instance)  
 }  

This is nice as it allows us to pass in any type of fruit, without having to cast it down to the base class. So I can do the following:

 IFoo<Fruit> fruitbowl = new Foo<Fruit>();  
 fruitBowl.TakeSomething(new Apple());  
 fruitBowl.TakeSomething(new Banana());  
 fruitBowl.TakeSomething(new Apple());  

Wednesday 27 April 2011

Kata video using nunit and resharper

The below video is well worth watching if you do TDD and use resharper and Nunit. I picked up a few tricks watching it.

I didn't know you could do the following to a test :

 [TestCase(argument1, argument2)]  
 [TestCase(argument1, argument2)]  
 [TestCase(argument1, argument2)]  
 [Test]  
 public void Test(string argument1, string argument2) {  
 Assert.AreEqual(argument1, argument2);  
 }  

It allows us to run the same test multiple times with different arguments. DRY!



Calculator Code Kata Cast 1 from Rickard Nilsson on Vimeo.

Scaling sitecore

One of the sites I look after is www.mcfc.co.uk . I am not sure I am allowed to release the stats, but  on a match day we can get a lot of page views in 24 hours. With the announcement of a high profile transfer signing, it can be many more. What follows is a brief overview of the setup and some of the things we do to help the site scale.

The site currently runs on sitecore 6.2, although we have plans to move to 6.4. In production we currently have 2 cms servers ( one is a redundant backup ) and 4 front end servers sitting behind a load balancer just serving content.

To manage the state across the servers we use memcached to store session data. We have two memcached servers to provide redundancy.

Cache clearing across the front end servers is done using the staging module ( it does have its quirks admittedly).

The database server is a huge clustered beast to ensure we have some redundancy. Each web server has it's own web database, so that we can safely update one server at a time.

We also employ a CDN provider called limelight to handle the serving of media such as images, video, CSS & JS. This takes a huge strain off of the servers as sitecore usually stores the images in the database.

To help reduce the load on the database server, we store all of the news, videos ect in a lucene index. This saves us having to do lots of really slow GetItems() queries.

We have also set up some maintenance tasks to ensure the database indexes do not get fragmented. At one point, our indexes were 98% fragmented and our database server was taking a pounding. A quick rebuild on the main tables and it made a huge difference.

Below is a query to help you find out how fragmented a table is:

 DECLARE @db_id SMALLINT;  
 DECLARE @object_id INT;  
 SET @db_id = DB_ID(N'ManCitySitecore_Web_Phase3');  
 SET @object_id = OBJECT_ID(N'Items');  
 IF @db_id IS NULL  
 BEGIN;  
   PRINT N'Invalid database';  
 END;  
 ELSE IF @object_id IS NULL  
 BEGIN;  
   PRINT N'Invalid object';  
 END;  
 ELSE  
 BEGIN;  
   SELECT * FROM sys.dm_db_index_physical_stats(@db_id, @object_id, NULL, NULL , 'LIMITED');  
 END;  
 GO  

AOP - caching with postsharp

Aspect oriented programming is a nice way of keeping your code clean.  Essentially what it allows us to do,  is place various attributes on a method of class declaration which can perform various actions for us without cluttering up our logic.

The example below has a cache aspect declared meaning that the data returned can be cached.

  [Cache(CacheType.Absolute, 120)]  
     public Dictionary<string, string> GetData(string rawUrl)  
     {  

Postsharp extends msbuild and as a result it does extend a compile time a little bit, but it is not obviously noticeable. Using postsharp, we can  hook into the events that happen before and after a method is called. In this case we are intercepting before a method is called.

  [Serializable]  
   public sealed class CacheAttribute : MethodInterceptionAspect  
   {  
     private readonly CacheType m_cacheType;  
     private readonly int m_expiry;  
     public CacheAttribute(CacheType cacheType, int expiry)  
     {  
       m_cacheType = cacheType;  
       m_expiry = expiry;  
     }  
     public override void OnInvoke(MethodInterceptionArgs context)  
     {  
       object value;  
       var key = GenerateKey(context);  
       if (!CacheHelper.Get(key, out value))  
       {  
         // Do lookup based on caller's logic.   
         context.Proceed();  
         value = context.ReturnValue;  
         CacheHelper.Add(value, key, m_cacheType, m_expiry);  
       }  
       context.ReturnValue = value;  
     }  
     private static string GenerateKey(MethodInterceptionArgs context)  
     {  
       var keyBuilder = new StringBuilder();  
       keyBuilder.Append(context.Method.GetHashCode());  
       foreach (var arg in context.Arguments.ToArray())  
       {  
         keyBuilder.Append(arg.GetHashCode());  
       }  
       return keyBuilder.ToString();  
     }  
   }  

Here is the CacheHelper class referenced above:

 public enum CacheType  
   {  
     Absolute,  
     Sliding  
   }  
   public static class CacheHelper  
   {  
     private static CacheItemPolicy GetCachePolicy(CacheType type, int expiry)  
     {  
       var policy = new CacheItemPolicy();  
       switch (type)  
       {  
         case (CacheType.Absolute):  
           policy.AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(expiry);  
           break;  
         case (CacheType.Sliding):  
           policy.SlidingExpiration = new TimeSpan(0, 0, 0, expiry);  
           break;  
       }  
       return policy;  
     }  
     /// <summary>  
     /// Insert value into the cache using  
     /// appropriate name/value pairs  
     /// </summary>  
     /// <typeparam name="T">Type of cached item</typeparam>  
     /// <param name="o">Item to be cached</param>  
     /// <param name="key">Name of item</param>  
     /// <param name="cacheType">Cache Expiration type</param>  
     /// <param name="expiry">Expiry time in seconds</param>  
     public static void Add<T>(T o, string key, CacheType cacheType, int expiry)  
     {  
       var cacheItem = new CacheItem(key, o);  
       MemoryCache.Default.Add(cacheItem, GetCachePolicy(cacheType, expiry));  
     }  
     /// <summary>  
     /// Remove item from cache  
     /// </summary>  
     /// <param name="key">Name of cached item</param>  
     public static void Clear(string key)  
     {  
       MemoryCache.Default.Remove(key);  
     }  
     /// <summary>  
     /// Check for item in cache  
     /// </summary>  
     /// <param name="key">Name of cached item</param>  
     /// <returns></returns>  
     public static bool Exists(string key)  
     {  
       return MemoryCache.Default.Contains(key);  
     }  
     /// <summary>  
     /// Retrieve cached item  
     /// </summary>  
     /// <typeparam name="T">Type of cached item</typeparam>  
     /// <param name="key">Name of cached item</param>  
     /// <param name="value">Cached value. Default(T) if item doesn't exist.</param>  
     /// <returns>Cached item as type</returns>  
     public static bool Get<T>(string key, out T value)  
     {  
       try  
       {  
         if (!Exists(key))  
         {  
           value = default(T);  
           return false;  
         }  
         value = (T)MemoryCache.Default.Get(key);  
       }  
       catch  
       {  
         value = default(T);  
         return false;  
       }  
       return true;  
     }  
   }  

So anytime I want to add caching to a repository now, I just add this aspect (attribute) to my method. The same can be applied for concepts just as easily for logging and transaction handling.

(Neil Duncan wrote this code originally btw!)

Domain Events

We recently trialled using domain events in one of our .net applications. Domain events are basically a simple way to delegate functionality to allow you keep you code clean.

The most common use is for you to raise an event which will send an email after completing some action, but there are many more uses.

First we have a class that will handle all ensure any events for a particular action (TEvent) are processed.

 public class EventNotifier : IEventNotifier  
   {  
     public void Notify<TEvent>(TEvent @event) where TEvent : class, IDomainEvent  
     {  
       var handlers = DependencyInjector.Instance.GetAllInstances<IHandle<TEvent>>();  
       foreach (var handler in handlers)  
       {  
         handler.Handle(@event);  
       }  
     }  
   }  

All of the events for a given action will implement a simple marker interface called IHandle and by using generics we can inject the events at runtime.

 public interface IHandle<in TEvent> where TEvent : class, IDomainEvent  
   {  
     void Handle(TEvent @event);  
   }   

An event is effectively just a model which we create and pass into our event notifier.

 public class FeedbackSubmitted : IDomainEvent  
   {  
     public Feedback Feedback { get; private set; }  
     public FeedbackSubmitted(Feedback feedback)  
     {  
       Feedback = feedback;  
     }  
   }  

The class that performs the action for a given event is pretty simple. It just needs to implement the Handle method for the given type (event - which is just a class!).


 public class OnFeedbackSubmittedSendEmail : IHandle<FeedbackSubmitted>  
   {  
     private readonly IEmailTemplateRepository m_emailTemplateRepository;  
     private readonly IFeedbackEmailSettings m_mailSettings;  
     private readonly IMailService m_mailService;  
     public OnFeedbackSubmittedSendEmail(IEmailTemplateRepository emailTemplateRepository, IMailService mailService, IFeedbackEmailSettings mailSettings)  
     {  
       m_emailTemplateRepository = emailTemplateRepository;  
       m_mailService = mailService;  
       m_mailSettings = mailSettings;  
     }  
     public void Handle(FeedbackSubmitted @event)  
     {  
       var template = m_emailTemplateRepository.GetFeedbackTemplate();  
       if (template != null)  
       {  
         var feedback = @event.Feedback;  
         var message = template.CreateMessage(new MailAddress(m_mailSettings.FeedbackEmailTo),  
                                 new Hashtable  
                                   {  
                                     {"dateSubmitted", feedback.Posted},  
                                     {"firstName", feedback.FirstName},  
                                                    {"lastName", feedback.LastName},  
                                     {"email", feedback.EmailAddress},  
                                     {"phone", feedback.PhoneNumber},  
                                                       {"comment", feedback.Comment}  
                                   }  
           );  
         m_mailService.SendMail(message);  
       }  
     }  
   }  

So once we have set all this up, we can continue to add actions for the event without modifying our core business logic. It allows us to avoid having our services becoming very cluttered.

Tuesday 26 April 2011

Model View Presenter (MVP) and Sitecore

There are various ways to try and abstract our interaction with sitecore. The two most common that we have used are the Model View Presenter (MVP)  and MVC ( Model View Controller) patterns. In this post I will talk about how to use MVP with sitecore.

FIrst of: Don't use XSLT. It is untestable.

We start of with a base user control that all our controls will extend. All we are doing here is injecting the Presenter using structure map ( abstracted away inside DependencyInjector) and then calling a common method that will exist on all presenters, Init(). It also provides some common properties that we will be using later on.

 public class MVPUserControl<TPresenter> : BaseUserControl  
     where TPresenter : MVPPresenter  
   {  
     protected override void OnInit(EventArgs e)  
     {  
       var presenter = DependencyInjector.Instance.GetDefaultInstance<TPresenter>();  
       presenter.View = this;  
       IntegrateWithPresenter(presenter);  
       presenter.Init();  
       base.OnInit(e);  
     }  
     public bool IsFirstViewing  
     {  
       get { return !IsPostBack; }  
     }  
     public Guid CurrentItemId  
     {  
       get { return Sitecore.Context.Item.ID.ToGuid(); }  
     }  
     public string CurrentItemName  
     {  
       get { return Sitecore.Context.Item.Name; }  
     }  
     public string LanguageCode { get { return "UK"; } }  
     public string RegionCode { get { return "2"; } }  
     public virtual void IntegrateWithPresenter(TPresenter presenter) { }  
   }  


In the user control ( the view) we keep it very simple and it should just be used to pass information from and to. This way we can make it conform to an interface and as a result we can mock it using different frameworks.

The interface:

 public interface IView : IMVPView  
   {  
     string SectionTitle { set; }  
     IList<FaqItem> Questions { set; }  
   }  


The Implementation:

 public partial class FaqSection : MVPUserControl<Presenter>, IView  
   {  
     public string SectionTitle { protected get; set; }  
     public IList<FaqItem> Questions  
     {  
       set  
       {  
         rptFaqs.DataSource = value;  
         rptFaqs.DataBind();  
       }  
     }  
   }  

As you probably saw from our base user control, our presenter get magically wired up and it calls the Init() method when loaded.

The Presenter base class:

 public class MVPPresenter<TView> : MVPPresenter where TView : IMVPView  
   {  
     public new TView View  
     {  
       get { return (TView)base.View; }  
       set { base.View = value; }  
     }  
     protected internal override void CheckViewType(object view)  
     {  
       Type viewType = view.GetType();  
       Type allowedType = typeof(TView);  
       if (viewType != allowedType && allowedType.IsAssignableFrom(viewType) == false)  
         throw new InvalidOperationException(Resources.Constants.ObjectType + " " + viewType.Name + Resources.Constants.NotAllowed + " " + GetType().Name);  
     }  
   }  
   public abstract class MVPPresenter  
   {  
     private object m_view;  
     public object View  
     {  
       get { return m_view; }  
       set  
       {  
         CheckViewType(value);  
         m_view = value;  
       }  
     }  
     public virtual void Init() { }  
     protected internal virtual void CheckViewType(object view) { }  
   }  



The Presenter:


  public class Presenter :MVPPresenter<IView>  
   {  
     private readonly IFaqRepository m_repository;  
     public Presenter(IFaqRepository repository)  
     {  
       m_repository = repository;  
     }  
     public override void Init()  
     {  
       base.Init();  
       var section = m_repository.GetFaqSection(View.CurrentItemId);  
       View.Questions = section.Questions;  
       View.SectionTitle = section.SectionTitle;  
     }  
   }  
As you can see, all the asp.net and sitecore nastiness (Sitecore.Context.Item) is hidden in the view. The presenter just deals with initiating the repositories and doing some simple logic and passing it down to the view.

I can test this code. Happy days!

Sitecore cache clear

Sometime you just need to clear the caches on a sitecore server. Use the script below to save having the sitecore folder on your front end web server.

 <script language="CS" runat="server">  
  protected override void OnLoad(EventArgs e)  
  {  
  if (Request.QueryString["ClearCache"] != null)  
  {  
   Sitecore.Context.Database = this.WebContext.Database;  
   Sitecore.Context.Database.Engines.TemplateEngine.Reset();  
   Sitecore.Context.ClientData.RemoveAll();  
   Sitecore.Caching.CacheManager.ClearAllCaches();  
   Sitecore.Context.Database = this.ShellContext.Database;  
   Sitecore.Context.Database.Engines.TemplateEngine.Reset();  
   Sitecore.Caching.CacheManager.ClearAllCaches();  
   Sitecore.Context.ClientData.RemoveAll();  
   InfoLiteral.Text = "All sitecore cache has been cleared. DateTime:" + DateTime.Now.ToString();  
  }  
  else  
  {  
   InfoLiteral.Text = "You haven't entered correct query parameter. DateTime:" + DateTime.Now.ToString();  
  }  
  base.OnLoad(e);  
  }  
  private Sitecore.Sites.SiteContext WebContext  
  {  
  get  
  {  
   return Sitecore.Configuration.Factory.GetSite(Sitecore.Configuration.Settings.GetSetting("stagingSiteContext", "website"));  
  }  
  }  
  private Sitecore.Sites.SiteContext ShellContext  
  {  
  get  
  {  
   return Sitecore.Configuration.Factory.GetSite("shell");  
  }  
  }  
 </script>  

Enjoy!

Sitecore rebuild

If you run a sitecore setup with multiple front end servers, you will find that you occasionally need to manually rebuild the lucene indexes or the link database.

Place the script below in the root of your site. Very Handy.

  <script runat="server">  
     public string Database  
     {  
       get  
       {  
         return string.IsNullOrEmpty(Request["dbname"]) ? "web" : Request["dbname"];  
       }  
     }  
     protected void Page_Load(object sender, EventArgs e)  
     {  
       var database = Sitecore.Configuration.Factory.GetDatabase(Database);  
       if (Request.QueryString["index"] == "true")  
         RebuildIndexes(database);  
       if (Request.QueryString["link"] == "true")  
         RebuildLinksDatabase(database);  
     }  
     protected void RebuildIndexes(Sitecore.Data.Database database)  
     {  
       if (database != null)  
       {  
         DateTime start = DateTime.Now;  
         for (int i = 0; i < database.Indexes.Count; i++)  
         {  
           WriteToResponse(String.Format("Rebuilding {0} index", database.Indexes[i].Name));  
    try {  
           database.Indexes[i].Rebuild(database);  
    }  
    catch(Exception ex)  
    {  
    WriteToResponse("Error while rebuilding index: " + ex.Message);  
    }  
           WriteToResponse(String.Format("Index {0} rebuilt", database.Indexes[i].Name));  
         }  
         TimeSpan elapsed = DateTime.Now - start;  
         WriteToResponse("Indexes rebuilt in " + elapsed.TotalMilliseconds + " ms");  
       }  
     }  
     protected void RebuildLinksDatabase(Sitecore.Data.Database database)  
     {  
       WriteToResponse("Rebuilding Links database");  
       DateTime start = DateTime.Now;  
       Sitecore.Globals.LinkDatabase.Rebuild(database);  
       TimeSpan elapsed = DateTime.Now - start;  
       WriteToResponse("Links database rebuilt in " + elapsed.TotalMilliseconds + " ms");  
     }  
     protected void WriteToResponse(string str)  
     {  
       Response.Write(str + "<br/>");  
       Response.Flush();  
     }      
   </script>  

Our dev team

The team on a project is generally made up of the following people.

Technical Director:
Responsible for overall technical output of Aqueduct

Lead Developer:
Responsible for and leads projects technically; they also mentor and lead other developers

Senior Developers:
Ensure projects are developed to the best technical standards

Senior Front End Developer:
The Front End Team is responsible for Aqueduct front end output quality and adherence to W3C  and government standards

Dedicated tester:
The tester is the lynchpin between the PM’s and the developers, the tester is responsible for the writing and execution of ad-hoc, automated and regression tests on projects to ensure the code is delivered with the best quality possible without jeopardizing existing code.

Methodology

The majority of our big projects follow the scrum methodology.  I won’t bore you with the details of scrum, as there are various good sources around the Internet.  I’ll just provide some of the more interesting things we have learnt from using it for a few years.

1) A one-week sprint is not long enough.
No matter how good your intentions, you never end up with anything finished in one week. The overhead just becomes too much.

2) Hold a pre-planning session.
On big projects, planning the stories for a two-week sprint can become a chore and people get bored very quickly. The lead developer on the project should sit down with the PM before the session and write the stories and the basis for the acceptance criteria.  Planning sessions will go much quicker after this.

3) A developer must commit to a story.

When pointing a story, the developer doing the work must commit to the work being done. The PM should have no influence on how long story X will take. // Need to explain why

4) Make your project manager / scrum master read the  Mythical Man Month .
Just because you add a developer to a team, does not mean you will finish it quicker.  We generally find that you shouldn’t have more than 3/4 dev’s in one team. It just becomes onerous after that.
           
5) Ensure the Lead Developer on the project has an understanding partner!
            Enough Said. (Sorry, Hazel made me write this.)           
            

Developer Environment

Setting up a development environment is a relatively simple thing to do, but getting it right is more difficult and is something that should be constantly revised based upon project/sprint retrospectives.  We have gone through several iterations here at Aqueduct, in order to get something that we think it works quite well.

Dev machines
Developers must have good machines. Very Good Machines. Dual monitors are a must.
Tools
Good tools are a must. We use the following:
Resharper 5 – Lifesaver plugin.
VS2010 – Our IDE of choice.
Ants Profiler – For checking for performance issues.
Liquibase,  - For Versioning database changes
Apache bench – For load testing
TortiseSVN / GitBash – For source control management
Visual SVN Server – Takes the pain out of hosting subversion on Windows
            Firebug – The legendary plugin.
NUnit
Selenium
                        NCover
Moq

Source Control
We generally use subversion but we have been experimenting with GIT and Mercurial recently. Personally I like Git and we trailed it on a recent project. Unfortunately, we found that Git has quite a steep learning curve  (compared with subversion) and we chose to trial it of a fairly short project (8-10 weeks) with 5 developers.  I don’t think this was a long enough period for every one to adapt to it and we encountered lots of merge issues and it put everyone on the project under a fair bit of pressure. We are going to persevere with it and trial it on a longer project as we can see the potential benefits.

Test Driven Development
TDD is something we have been pushing at Aqueduct for a while. Although we are not fully there yet, we are getting there.  We generally use Moq and its powerful fluent structure in combination with Nunit to create our tests. Mocking in combination with the MVP pattern (where we can’t use MVC) allows us to bypass the problems generally faced when developing with webforms.

Code Coverage
We generally aim for around 50% code coverage on projects.  I personally feel that although having 100% coverage is possible; it is not worth the extra effort. You end up just testing setting properties on a view, which does not really tell you much. I prefer to test the actual business logic.

Continuous Integration
Having a continuous integration setup is at the centre of everything we do.  It allows to know the current status of the code as soon as someone does a check-in, instead of finding issues when we deploy.

We use CruiseControl.Net in combination with CCTray. At the start of each project we setup three different builds.

 CI Build (Run on every check-in)
·      Runs Unit Tests
·      Runs Selenium Tests
·      Computes code coverage

Nightly Build
·      Runs Unit Tests
·      Runs Selenium Tests
·      Computes code coverage
·      Deploys to DEV server

Staging Build (Manually triggered)
·      Runs Unit Tests
·      Runs Selenium Tests
·      Computes code coverage
·      Deploys to Staging / QA server

      


FFS, talk to people. Please.

If you are a programmer, please, for the love of god, don't just sit in your geek bubble with metalica blearing.

Interact with the creative department, some of them, as much as I hate to admit it, are actually pretty fucking clever. You are more likely to create better things that you are proud of, if you work together as opposed to just shunning them as they "don't get code".

Don't be "the guy in the room." Don't be the guy coding in the dark office emerging only to buy cola. The guy in the room is out of touch, out of sight, and out of control and has no place in an open, collaborative environment. - http://www.code-magazine.com/Article.aspx?quickid=1105121

Things to know before leading a development project

1) You will sleep less than you used to. ( Apologise to your partner before you start - or your mum if you still live at home!)

2) You will code less than you used to.

3) You will quickly learn that you don't know as much as you thought. Don't take this the wrong way. You can not know everything. If people around you are teaching you things, you are in the right place. You don't want to be somewhere where you stop learning.

Time to ditch NVelocity?

I have used Nvelocity on various projects over the years. It has always been a handy tool to have around, especially for email templates. The biggest pain in the arse with nvelocity, was that if you did some refactoring with resharper, (or god forbid, manually), it would not propagate the changes to my templates. You were also forcing front developers to learn another syntax, which was not always obvious if you wanted to do something non standard.

After experimenting with MVC in recent projects and in particular the razor view engine of late, I think I may have finally found a replacement. Razor was built to be standalone and as a result, you can easily use it as the templating system for generating emails. All the front end developers I have worked with like razor and they are already using for the main application views. The biggest win? Resharper supports the refactoring of razor views!

A quick google showed up several people who seemed to have the same idea.