New Blog

I have now closed the Clicktricity blog. whilst I remain focused on .NET I have other interests including architecture, design, agile and have therefore moved everything to a new site.  All previous Clicktricity content will remain here for a while, but for newer content please go to the new site.

timcromarty.com

Thanks

 

When to fix and when to rewrite

We have all faced the dilemma of whether to fix or rewrite software. Unfortunately it’s never a straight forward decision. Many industry heavyweights say NEVER rewrite, whilst others say it is only OK in specific circumstances.

The reasons for wanting a rewrite are usually based on the following:

The existing code is crap: the code displays all the features of a big ball of mud, and exhibits the usual code smells that indicate the code should be quietly taken outside, lined up against a wall and shot – the code that is, not necessarily the developers, but sometimes…

We now understand what it’s supposed to do: Agile development techniques build of the principles of only delivering what is immediately needed or know. This is then added to and extended continuously as new requirements, features and understandings emerge.  Without rigorous attention to refactoring, the code base quickly descends into a quagmire of modified methods, classes and objects that are now doing things they were never initially intended to do.

We want to use this new funky programming language: With the plethora or new languages, tools and techniques. MVC, JavaScript libraries, document databases, new devices, mobiles, tablets…

We need a bunch of new functionality: we want to add these great new features.

In most cases, don’t do itdo not rewrite from scratch. It is well documented that rewriting and existing application from scratch is almost always a bad thing:

  • It almost always takes much more effort than you expect.
  • What is to say that your New code is that much better than the old. It is well know that developers always want to work on the new, latest, shiniest piece of code. Working on old code is always Hard, especially if you didn’t write it in the first place.
  • It is usually far more complex than you anticipate. The original developers resolved a series of problems to come up with their final solution. You will probably need to resolve those problems again – so why reinvent what has already been done?

When is a rewrite acceptable?

However, there are some cases where a rewrite is the only alternative:

When the cost of inaction far outweighs the cost of action

This means that if you can measure the cost or risk of not rewriting your application, and compare that with the costs and risks of a rewrite then it’s a no-brainer. I have worked on applications that are so completely screwed that even an infinite number of monkeys with typewriters would give up and go to StarBucks. that’s when you know a rewrite is inevitable.

When a major platform change is required

If you find that you need to move say from console/character based to windows/web based, and the existing UI is heavily embedded in the existing code a rewrite may be more cost effective.

When a very significant change or addition of functionality is needed

You need to make the application do something it was never ever designed to do. “That functionality we said We will never ever need… Well things have changed!”

Try not to start from scratch

Given the indicators above, even if a rewrite appears to be the only viable option, if the technology allows you should always try to migrate, refactor, adapt or re-engineer your existing application. You will be starting from a (hopefully) working application and re-using whatever existing code or functionality that is salvageable. There are a number of techniques for doing this from standard refactoring to my favourite the Strangler method .

When all else fails

On those occasions when there really is no choice but to start again, do it properly. Go back to your business owners, customers or designers and start from scratch in understanding exactly what he new application is required to do. Do not copy the old application. Do not look at the source code of the old application. Do not look at the database design of the old application. Start from scratch with a clean and clear set of prioritized must have features and functions.

Of course, review the old application from a functional perspective. What features work, what don’t work, what could be improved.  However, beware of reproducing faithfully all the functionality especially that which is either superfluous or more worrying put into place to work around other issues or other systems.

Javascript Friendly Date and Time

I recently had a requirement in javascript to translate a date and time into something more friendly, so that for example 10th January 2014 10:45 becomes “Yesterday 10:45”, or 12:15 today becomes “2 hours ago”. After scanning the various solutions I could find, I came up with the following:

  • < 5 minutes: now
  • < 1 hour: xx minutes ago
  • today: today hh:mm
  • yesterday: yesterday hh:mm
  • < 7 days: day-of-week hh:mm
  • this year: month day
  • default: month day year
function friendlyDate(dateValue) {
    // < 5 mins   : now
    // < 1 hour   : xx minutes ago
    // today      : today hh:mm
    // yesterday  : yesterday hh:mm
    // < 7 days   : day of week hh:mm
    // this year  : month + day
    // default    : month + day + year
    var dateparts = dateValue.toUTCString().split(' '); // Thu May 29 2014 10:09:32 GMT+0000 (GMT)
    var weekdays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
    var now = new Date();

    var diffMsec = now.getTime() - dateValue.getTime();
    var diffMins = Math.round(diffMsec / 60000);

    if (diffMins < 1) {
        return "now";
    } else if (diffMins === 1) {
        return "1 minute ago";
    } else if (diffMins < 60) {
        return diffMins + " minutes ago";
    }

    // ignore time component
    var testDate = new Date(dateValue);
    testDate.setHours(0, 0, 0, 0);
    now.setHours(0, 0, 0, 0);
    var mSecPerDay = 24 * 60 * 60 * 1000; // hours * minutes * seconds * milliseconds
    var diffDays = Math.round(Math.abs((now.getTime() - testDate.getTime()) / (mSecPerDay)));

    if (diffDays === 0) {
        return "today " + dateparts[4].substr(0, 5);
    } else if (diffDays === 1) {
        return "yesterday " + dateparts[4].substr(0, 5);
    } else if (diffDays < 7) {
        return weekdays[dateValue.getDay()] + ' ' + dateparts[4].substr(0, 5);
    }

    if (dateValue.getFullYear() === now.getFullYear()) {
        return dateparts[1] + ' ' + dateparts[2];
    }

    return dateparts[1] + ' ' + dateparts[2] + ', ' + dateparts[3];
}

You can try this out on jsfiddle

Another book: ASP.NET jQuery Cookbook

ASP.NET jQuery Cookbook
I’ve been editing another book!

This one covers many aspects of using jQuery within ASP.NET in a WebForms based environment. If you are new to the combination of jQuery and WebForms (aspx) then I thoroughly recommend this as a great introduction.

It includes the following:

  • Tips and tricks for interfacing the jQuery library with ASP.NET controls
  • Boost ASP.NET applications with the power of jQuery
  • Use a problem-solution based approach with hands-on examples for ASP.NET developers
  • Step-by-step guide with plenty of code snippets and screen images
  • Simple, effective, and easy-to-follow recipes
  • eBook available as PDF and ePub downloads

For more details, see the publisher’s page here.

ASP.NET MVC 2 Cookbook

ASP.NET MVC 2 Cookbook

Over the past year or so, I have had the pleasure to technically review this book, chapter by chapter and revision by revision.  The final result is an extremely useful collection of ‘recipes’ that will add extra functionality in most MVC applications and help you to understand some of the key concepts.

For more details, see the Packt website here

Principles of Agile Development

Since taking down the old Clicktricity website, I have had a number of requests to re-publish the agile principles.

Agile Development Core Values

The two most important core values of Agile Development are Communication and Simplicity.

Communication

It is recognised that poor communication in software teams is one of the root causes of failures within projects – whether it be schedule slips, botched requirements, misunderstandings, faulty development assumptions, and the like. Extreme Programming mitigates this by stressing good communication between all project stakeholders – customers, team members, and project managers (or “coaches”) – on a consistent basis. A representative from the customer should be available as much as possible to answer questions and clarify project requirements. Programmers often work simultaneously in pairs, with each programmer reviewing the other’s work.

Simplicity

One of the most common XP slogans is “YAGNI” or ‘You Aren’t Going to Need It’

The principal of YAGNI is that you shouldn’t develop any code that will only be used by a feature that is needed tomorrow. This does not exclude development of flexibility, but it should be kept in check and only functionality that is required now is actually developed.

Agile Development Principles

User Stories

User stories are short, simple descriptions of required functionality that are written by the customer, rather than our interpretation of what the customer wants. The descriptions should only contain sufficient detail to allow development of an accurate estimate for planning purposes, development of unit tests, and are used instead of large unwieldy requirements documents. When we develop and implement the user stories, the developers will work face-to-face with the customer to determine the specific detailed requirements.

Planning

The Planning phase of development is performed in two parts – firstly the “user stories” described above are elicited from the customer. Secondly, the development team estimates development effort for each story. The customer then decides on priorities and agrees what user stories will be implemented in the next release. This defines the project schedule.

Small Releases

The planning phase determines small units of functionality that make good business sense and can be released into the customer’s environment early in the project. This is critical to getting valuable feedback in time to have an impact on the system’s development.

Design Simplicity

The overwhelming aim is to make things as simple as possible. The only code being worked on should be the code that is absolutely necessary to implement the latest user stories, and no more (see YAGNI, as described previously). The drive for simplicity leads to continual refactoring of code, as described below.

Testing

Testing, and in particular writing test specifications from the user stories before coding is another essential component of this technique. Traditional development techniques that follow a “code first, test later” technique are prone to only testing a limited part of the development. In addition it is common that as schedules become tight – thorough testing is often dropped in the interest of expediency, leading to low quality, error prone code. Our technique is to define and develop automated tests before coding ensuring that untested code cannot be released.

Pair Programming

In pair programming, one member of the pair will write code while at the same time another programmer is critiquing the work at hand, and at the same time offering insight as to the next step as well as exposing trivial defects with the code. In tests, pair programming has been shown to be 30% more productive when quality is taken into account, than the combined productivity of two developers working separately.

Refactoring

Once it becomes apparent to the development team that the system design, a module or piece of individual code is becoming too complex, the code is refactored. The refactoring process is one by which the system functionality remains stationary – all tests that pass prior to refactoring should pass after refactoring is completed – but the code base becomes greatly simplified. This may involve eliminating shared code, redesigning model hierarchies and relationships, or simply renaming variables to fit a particular metaphor.

No Overtime

A standard working week with no overtime is strictly adhered to, based on the assertion that development teams are able to produce high-quality product when they are comfortable and not overly-exerted. This principle serves to complement the idea of both pair programming and communication amongst the development team and their customer.

Customer Availability

It is not enough to have only occasional access to a customer and a customer representative should be continuously available to the development team. This ensures that all unanticipated questions or requirements can be immediately resolved and eliminates the need to produce exhaustive and definitive (and probably still incomplete and non-definitive) specifications at the beginning of the project. This also allows the customer to interact with the development and help in the evolution of the product. Maximizing customer availability makes it possible to minimize the time spent on preliminary planning and focus on development, and maximize feedback, thereby increasing the value delivered to the customer.

Coding Standards

The entire development team agrees to maintain a common set of rules concerning the maintenance and creation of new code. These standards greatly simplify communication through common naming conventions and generate shared ownership and responsibility among all developers.

For more information on the principles of Extreme Programming, please see

Clicktricity 5D Methodology

Since taking down the old Clicktricity website, I have had a number of requests to re-publish my 5D development methodology and the agile principals.

Clicktricity 5D

Clicktricity 5D is an agile application development methodology that drives delivery of cost-effective, repeatable, quality solutions in an adaptable framework that suits software development and application implementations for both small and large enterprises.
 
The 5D methodology allows us to consistently provide the following:

  • Accurately determine business and commercial requirements
  • Design solutions that meet client’s short and long terms needs
  • Develop quality applications, on-time, on-budget
  • Implement solutions with minimal impact to ongoing business operations
  • Provide comprehensive handover and ongoing support of delivered solutions
The 5D methodology is an iterative process consisting of the following standard phases, which may be repeated as necessary for each phase and sub-phase of a project/

1. Discover

Analysts and solution architects work closely with the client to understand and accurately document the business, commercial and operational requirements. They map out the project timeline, risks, impact and deliverables, and divide the project up into short, medium and long term achievable and measurable milestones in order that progress can be accurately tracked, monitored and managed.

2. Design

The detailed design stage builds upon the initial discovery analysis and describes in detail exactly what is required, how it will be achieved and the process that will be used to produce the final result.

3. Develop

Using an iterative cyclical process, we develop, test and QA the solution according to required quality and development standards. In addition, we keep the customer involved in every step of the development process including functional prototypes and pre-release candidates.

4. Deliver

Deliver the completed solution and install it in the customer’s environment. Then work with the customer to complete acceptance tests and verification of functionality.

5. Deploy

Work closely with the client’s resources to deploy the application, complete the handover, documentation and provide any user training that is required. Complete a comprehensive post-project review to ensure that we have met every requirement.

Populating common view model attributes

In many ASP.Net MVC based applications, we often find ourselves needing to include the same information in every page.  Such information typically includes details of the current user, maybe environmental values and running totals like the number of items in a shopping basket.

In order to ensure these values are always available in views, base your view models on a common base class, and populate these base values using an action filter.

public class ViewModelBase
{
   public string UserName { get; set; }
   public List<UserFavorite> UserFavorites { get; set; }
   public ShoppingBasket ShoppingBasket { get; set; }
}

Then, create an action filter to populate this, if it has not already been populated by the action method on which it has been applied.

// Populates View Model base properties, if they are not already populated by the controller
class ViewModelAttribute : ActionFilterAttribute
{
   public override void OnActionExecuted(ActionExecutedContext filterContext)
   {
   ViewModelBase viewModel;

   if (filterContext.Controller.ViewData.Model == null)
   {
      viewModel = new ViewModelBase();
      filterContext.Controller.ViewData.Model = viewModel;
   }
   else
   {
      viewModel = filterContext.Controller.ViewData.Model as ViewModelBase;
   }

   if (viewModel != null)
   {
      viewModel.UserName = lookupUserName();
      viewModel.UserFavorites = GetUserFavorites();
      viewModel.ShoppingBasket = GetShoppingBasket();
   }

   base.OnActionExecuted(filterContext);
   }
}

The code first checks for a null model and assigns a base view model if none exists.  It then checks that if a model does already exist, that it is of type ViewModelBase.  If so, the appropriate values are initialized.

Then, on any action method that required this – or (in my case) at the controller level of a base controller class, add the attribute:

[ViewModel]
public abstract class ControllerBase : Controller
{
 /// Controller base

}

Rendering views to strings

Rendering a view or a partial to a string is a common problem, especially when you want to re-use your code and markup in a PDF or Email.  There are a number of semi-successful methods for achieving this across the internet.  The techniques outlined below are built on the excellent post from Kevin Craft at http://craftycodeblog.com/2010/05/15/asp-net-mvc-render-partial-view-to-string/ this has the advantage of being simple, straight forward and fully support embedded Html helpers.

Render Partial To String & Render Form To String

Define the following within a Controller base class:

public class BaseController : Controller
{
   protected string RenderPartialToString(string viewName, object model)
   {
      if (string.IsNullOrEmpty(viewName))
         viewName = ControllerContext.RouteData.GetRequiredString("action");

      ViewData.Model = model;
      using (StringWriter sw = new StringWriter())
      {
         ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
         validateViewResult(viewResult, viewName);
         ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
         viewResult.View.Render(viewContext, sw);
         return sw.GetStringBuilder().ToString();
      }
   }

   protected string RenderViewToString(string viewName, object model, string masterName)
   {
      if (string.IsNullOrEmpty(viewName))
      viewName = ControllerContext.RouteData.GetRequiredString("action");
      ViewData.Model = model;
      using (StringWriter sw = new StringWriter())
      {
         ViewEngineResult viewResult = ViewEngines.Engines.FindView(ControllerContext, viewName, masterName);
         validateViewResult(viewResult, viewName);
         ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
         viewResult.View.Render(viewContext, sw);
         return sw.GetStringBuilder().ToString();
      }
   }

   private static void validateViewResult(ViewEngineResult viewResult, string viewName)
   {
      if (viewResult.View != null)
      return;
      // wasn't found - construct error message
      StringBuilder locationsText = new StringBuilder();
      foreach (string location in viewResult.SearchedLocations)
      {
         locationsText.AppendLine();
         locationsText.Append(location);
      }
      throw new InvalidOperationException(String.Format("View {0} not found. Locations Searched: {1}", viewName, locationsText));
   }
}

Then, within your controller action methods you can use something similar to this:

string partial = RenderPartialToString("TestPartial", "This is my test partial");
string viewString = this. RenderViewToString("", null, "");

Using MVC RenderAction within a Webform

As pointed out in the previous post (<here>) it is possible to call the MVC RenderPartial from within a webform.  This assumes that your webform has all the information it needs to populate the required model.  Where this information is not available, a good alternative is to use RenderAction from within the webform:

Add the following to the MvcUtility class described in the previous post:

public static void RenderAction(string controllerName, string actionName, object routeValues)
{
   RenderPartial("RenderAction", new RenderActionViewModel() { ControllerName = controllerName, ActionName = actionName, RouteValues = routeValues });
}

Create the viewModel to support the data we want to pass:

public class RenderActionViewModel
{
   public string ControllerName { get; set; }
   public string ActionName { get; set; }
   public object RouteValues { get; set; }
}

And, create a partial view to make the RenderAction request (I put mine in the Shared directory)

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<RenderActionViewModel>" %>
<%Html.RenderAction(Model.ActionName, Model.ControllerName, Model.RouteValues); %>

Then, all that is needed is to call the MvcUtility.RenderAction from within a webform, passing it the name of the controller, action and and additional parameters that your action method requires.  Examples:

<% PartialViewHelper.RenderAction("myController", "myAction", new { param = Value }); %>
...
<% PartialViewHelper.RenderAction("Blogs", "List", new { page = 1, order = "date", comments = "off" }); %>

This is a great way of adding MVC functionality to a Webforms environment.