# Tuesday, 20 October 2009

Think big; act small; fail fast; learn rapidly.

These are some of the lessons from Tom and Mary Poppendieck’s book Lean Software Development – An Agile Toolkit.

The Poppendiecks take what they learned from Lean Manufacturing (many of which were originated with the pioneering work of Toyota Motor Company) and apply these lessons to software development.

They deliver advice in the form of 22 “tools” that can make a team or project more lean. Related tools are grouped together into chapters.

The authors recommend that organizations define, find and eliminate waste wherever it occurs in a process. Examples of waste in software development include defects, waiting, extra features or processes, and any non-essential activity. To assist finding waste, they recommend Value Stream Mapping - a technique in which one lists in sequences all the steps from customer request to delivery and estimates the time to completion of each step and the wait time between each step. This technique often makes bottlenecks obvious so that they can be reduced or eliminated.

Many of the tools in this book overlap. For example, iterations and feedback are listed as separate tools, but shorter iterations allow for more frequent feedback to the development team. Short iterations also expose design problems more quickly sot that the can be corrected early in the development cycle at a lower cost.

Much of the authors’ advice seems counter-intuitive. For example, they recommend against detailed planning at the start of a project and attempting to optimize every part of a multi-part project.

A popular approach among software project managers is to create in advance a detailed plan of every step in the design, development and deployment process and to estimate each step. To do so, you need to know a specific scope of everything you will build. This makes sense as a risk-reduction strategy, until you consider that environments, requirements, priorities and people often change while software is being developed. A rigid plan created up front often requires an aggressive change control process to alter that plan in any way. And for long-term projects, the changing landscape almost always forces changes to the design. Also, when users know they will only get one chance to request features, they tend to ask for far more, so scope tends to get bloated when projects are planned in this way. A better approach is to re-evaluate priorities periodically throughout the development process and keep focused on the top priority features that have not yet been implemented.

Complex project can and often should be split into a number of smaller phases or tasks. This helps to simplify the complexity. Many managers then strive to optimize each phase of the project, assuming that this goal will lead to overall optimization of the project. The Poppendiecks advise against this goal because optimizing some phases may cause a bottleneck in your overall project, thus slowing down the project as a whole. A buildup of code waiting to be tested, for example, represents waste that should be eliminated. It is best to look at the system as a whole when setting optimization goals. Optimizing each part ignores the interaction between these parts.

The book finishes with practical advice to get started making your team and process more lean.

Lean Software Development - An Agile Toolkit is a clearly-written, thoughtful book and anyone involved in software development projects can benefit from reading it.

Agile | Books
Tuesday, 20 October 2009 11:17:26 (GMT Daylight Time, UTC+01:00)
# Monday, 19 October 2009

Episode 59

In this episode, Chris Woodruff discusses how to use RIA Services to separate concerns in a Silverlight application.

Monday, 19 October 2009 03:15:45 (GMT Daylight Time, UTC+01:00)
# Friday, 09 October 2009

I will be presenting technical talks in Kalamazoo, MI and Grand Rapids, MI. My schedule is below.

Date Topic Event Location  
Oct 22 An Introduction to Object-Oriented Programming Microsoft Developers of Southwest Michigan October meeting WMU College of Engineering Building,
Rm C-123
Kalamazoo, MI
Info
Dec 3
Oct 29
Build Better Software with TFS and VSTS 2010 Sogeti-New Horizons - Microsoft event New Horizons
28th St. Court SE
Suite B
Grand Rapids, MI
Info

Also, my colleague Jesse Murray will be speaking about "SharePoint - The Right Way" at the Great Lakes Area .Net User Group Wednesday October 21 in Southfield, MI. This event is sponsored by Sogeti (so food will be provided). You can get more information here.

Edit: My VSTS 2010 / TFS 2010 talk scheduled for October 29 has been postponed to December 3.
    -Dave, 10/24

 

Friday, 09 October 2009 15:52:02 (GMT Daylight Time, UTC+01:00)
# Thursday, 08 October 2009

HopeMongers is attempting to connect people together via charitable donations. The web site HopeMongers.org allows individual contributors to donate small amounts of money (they use the term "Microgiving" to describe this) to individual projects that help the poor of the world.

By doing so, they eliminate much of the bureaucracy and cost that burdens many other charitable institutions. The projects that HopeMongers supports tend to be small in size and focused on an individual community. Examples include digging a well to provide clean drinking water for a village in Haiti; construction of a building to house an orphanage in Uganda; and a computer education center in South Africa.

"All the money that's donated to HopeMongers goes to the project" said lead architect Phil Japikse.

On the web site, each project lists the amount needed to fully fund it and the amount raised so far.

Sam Henry of Microsoft is the driving force behind this site and he has traveled around the world seeking, vetting and overseeing projects to show on the site.

But many others are involved in the development of the web site.

DiscountAsp.net donated the web hosting; SAAS hosts TFS and the build servers for free; and most of the development time was donated by dozens of talented developers. Those who didn't volunteer worked on the project at a discounted bill rate.

The development team was spread across the US and worked part-time, which presented a number of challenges. For instance, most of the collaboration took place between 10PM and 1AM Eastern time, via LiveMeeting. For those interested in the technology, the site is built using ASP.Net web forms built with JQuery, C# and NHibernate.

The site is now live and accepting donations. Visit http://www.HopeMongers.org  to learn about the projects and to give a little. You can even donate to the HopeMongers project itself from the site.

I gave $10 to help provide clean drinking water to a village in Uganda and I feel better for having done so.

Thursday, 08 October 2009 12:17:30 (GMT Daylight Time, UTC+01:00)
# Wednesday, 07 October 2009

Episode 58

In this interview, Sai Naik describes the advantages of SharePoint and where it is a recommended solution.

Wednesday, 07 October 2009 14:43:04 (GMT Daylight Time, UTC+01:00)
# Tuesday, 06 October 2009

The ASP.NET MVC framework (which I will refer to as "MVC" in this article) encourages greater separation of concerns than the older ASP.NET web forms framework.

Some key differences between web forms and  MVC are

  • ASPX pages in MVC have no code-behind files. This discourages developers from putting any business logic in the view.
  • By default, URLs in MVC do not point to a file on disc. Rather, they point to an Action in a Controller.

A controller is a class that inherits from System.Web.Mvc.ControllerBase.

MVC uses several conventions to find this class. First, it expects controller classes to be in the Controllers folder. Also, it expects a controller class name to end with "Controller".  So if we tell MVC to look for a Product controller, it will look for the file Controllers\ProductController.cs or Controllers\ProductController.vb.

An Action is a method within a Controller class that returns a System.Web.Mvc.ActionResult. The ActionResult represents the View data that is available when MVC renders output to the client.

One way we can tell MVC to look for a controller is by typing a URL into the browser’s address bar. Doing this causes MVC to use the routing engine. I described the routing engine in a previous article. The default routing assigned to a new MVC project looks for a URL with the following format

Controller/action/id

When the routing engine encounters a URL formatted like the one above, it looks for a controller named after the first part of the URL; an action method within that controller named after the second part of the URL; and a parameter to pass to that method in the third part of the URL. For example, if the user typed the following URL into the address bar:

Customer/Details/1

, MVC would look for a class named CustomerController in Controller\CustomerController.cs (assuming we are coding in C#). If it found this class, it would look in it for a method named "Details" that returns an ActionResult and that accepts a parameter. It would then call the Details method and pass it the parameter "1".

The ActionResult returned by this method is used by the MVC View engine to render output to the client. I described MVC views in a previous article.

The code below is for a Controller Action method. It assumes the existence of the GetCustomer method that returns a single customer object.

public ActionResult Details(Int32 id)
{
    Customer cust = MVCDemoRepository.GetCustomer(id);
    return View(cust);
}

The View method called in the code above returns a ViewResult – a class that inherits from ActionResult. By passing the Customer object to this method, the ActionResult’s Model property is populated with the Customer object. Properties of that object can then be used within the view.

Another way to pass data from the controller to the view is to populate the ViewData property. ViewData is a list of name-value pairs. You can populate this list in the controller and retrieve elements from it within the view. We can modify the Action method above to add to the ViewData list.

public ActionResult Details(Int32 id)
{
    ViewData["HelloMessage"] = "Good morning to you";
    Customer cust = MVCDemoRepository.GetCustomer(id);
    ViewData["GoodbyeMessage"] = "Good night. See you later";
    return View(cust);
}

By default, this controller routes the user to a view with the same name as the Action in a folder named after the controller. In this case, MVC will look in the \Views\Customer folder for a file named either Details.aspx or Details.ascx. If it cannot find either of these files in that folder, it will search in the Views\Shared folder. Here MVC is using configuration again to determine where to look for files.

You can change the view MVC looks for by using an overload of the View method as in the following example

return View("CustomerDetails", cust); 

The above line tells MVC to look for a view page named CustomerDetails.aspx or CustomerDetails.ascx in either \Views\Customer or \Views\Shared.

Here is a complete listing of a Controller class

using System;
using System.Collections.Generic;
using System.Web.Mvc;
using MVCDemoController.Models;

namespace MVCDemoController.Controllers
{
    public class CustomerController : Controller
    {
        // GET: /Customer/
        public ActionResult Index()
        {
            List<Customer> customers = MVCDemoRepository.GetAllCustomers();
            return View(customers);
        }

        // GET: /Customer/Details/1
        public ActionResult Details(Int32 id)
        {
            ViewData["HelloMessage"] = "Good morning to you";
            Customer cust = MVCDemoRepository.GetCustomer(id);
            ViewData["GoodbyeMessage"] = "Good night. See you later";
            return View(cust);
        }
    }
}

Below is a sample view to render the output from the Details controller action above

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MVCDemoController.Models.Customer>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Details
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <h2>Details</h2>

    <div>
    <%=Html.Encode(ViewData["HelloMessage"]) %>
    </div>
    <fieldset>
        <legend>Fields</legend>
        <p>
            ID:
            <%= Html.Encode(Model.ID) %>
        </p>
        <p>
            FirstName:
            <%= Html.Encode(Model.FirstName) %>
        </p>
        <p>
            LastName:
            <%= Html.Encode(Model.LastName) %>
        </p>
    </fieldset>
    <p>
        <%=Html.ActionLink("Back to List", "Index") %>
    </p>
    <div>
    <%=Html.Encode(ViewData["GoodbyeMessage"]) %>
    </div>

</asp:Content>

Details

Good morning to you
Fields

ID: 1

FirstName: David

LastName: Giard

Back to List

Good night. See you later

The MVC Controller is used to retrieve data from the Model, to populate any extra data needed by the view and to determine which view to render. Understanding it is key to understaning MVC.

Download demo code for this article at MVCDemoController.zip (281.08 KB)

 

ASP.NET | MVC
Tuesday, 06 October 2009 05:10:09 (GMT Daylight Time, UTC+01:00)
# Monday, 05 October 2009

Episode 57

In this interview, Dr. David Truxall discusses the art of debugging and dives into WinDbg and other tools to debug production issues.

Monday, 05 October 2009 13:01:31 (GMT Daylight Time, UTC+01:00)
# Sunday, 04 October 2009

The ASP.NET MVC framework (which I will refer to as "MVC" in this article) encourages developers to work closer to actual rendered HTML than does the more traditional web forms ASP.NET framework. The web form framework abstracted away much of the HTML, allowing developers to create sophisticated web pages simply by dragging controls onto a design surface. In fact, with the web forms framework, it is sometimes possible for someone with no knowledge of HTML to build an entire web application.

But MVC’s view engine removes that abstraction, encouraging users to write more of their own HTML. By doing so, developers also get more control over what is rendered to the client.

Some web developers may be surprised to learn that most of the server controls they are used to dragging onto a design surface do not work in MVC. This is because ASP.NET server controls are self-contained objects that encapsulate all their functionality, including the C# or VB code they run. This is contrary to the way that MVC works. In the MVC framework, all business logic code is in either the model (if it applies to the data) or in the controller if it applies to routing or output.

An MVC view consists only of an ASPX page. By default it doesn't even contain a code-behind file.

Let’s analyze a typical MVC view. Like a web form, an MVC view contains a page directive at the top.

<%@ Page Title="Sports" Language="C#" 
MasterPageFile="~/Views/Shared/Site.Master" 
Inherits="System.Web.Mvc.ViewPage<TestMvc.Models.Customer">
%>

The Title, Language and MasterPageFile attributes should be familiar to anyone who has developed in ASP.NET. The meanings of these attributes have not changed in MVC. The Inherits attribute is also used in web forms development, but in this case, we are inheriting from a ViewPage that contains our model.  The model represents the data we wish to render (I will write more about the MVC model in a future article.) By inheriting from a ViewPage, we provide the model data directly to the page and we can strongly type the keyword Model to whatever data type our model is.

Mixed in with the HTML of our page, we can output some server side data by enclosing it in <% %> tags.

If you wrote any web sites with classic ASP (the predecessor to ASP.NET), you probably used these tags. (I recently heard someone refer to them as "bee stingers").  If you place "=" in front of a value or variable, the view engine will output the value or contents of that variable. For example

<%=System.DateTime.Now %>

outputs the current date and time, like the following

10/2/2009 6:08:46 PM

We mentioned earlier that the Model keyword is strongly-typed. For example, If we inherit our ASPX from  System.Web.Mvc.ViewPage<TestMvc.Models.Customer>, then our model represents a Customer object and we can output a property of that model class.

Assuming that our Model is uses the following Customer class:

public class Customer
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

, we can output the FirstName property with the following markup:

<%= Model.FirstName %> 

You probably already know that it is almost always a bad idea to output text directly for the screen without encoding it, as I did above. Failure to do so may leave your site open to scripting attacks. Fortunately MVC includes an Encode helper method to encode strings for safer output. That helper method (along with other helpers) is available via the Html property of the ViewPage from which our view inherits. We can call the helper method and encode the first name with the following markup.

<%= Html.Encode(Model.FirstName) %>

This outputs the FirstName property, but encodes it to prevent problems if the first name property somehow gets infected with some client-side script.

Other helper methods of the ViewPage give you the ability to begin and end an HTML form, to render an HTML textbox, to render a hidden field, to render an HTML listbox, and perform many other useful functions.

The code below will output a hyperlink with the text "Home" that links to the Index method in the Home controller.

<%= Html.ActionLink("Home", "Index", "Home")%>

Another way to use data in the view is to store it in ViewData. ViewData is a property of the view and contains a dictionary of name/value pairs. You can add a value to this dictionary in the controller with code like the following

ViewData["Greetings"] = "Hello dummy";

and display a ViewData element in the view with markup like the following

<%= Html.Encode(ViewData["Greetings"]) %>

Below is the full markup for a sample MVC view page

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MVCDemoView.Models.Customer>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Index
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<div>
<%= Html.Encode(ViewData["Greetings"]) %>
</div>
<div>
<%= Html.Encode(Model.FirstName) %>
<%= Html.Encode(Model.LastName) %>    
</div>
<div>
<%= Html.ActionLink("Home", "Index", "Home")%>
</div>
</asp:Content>

Here is the output of the view page above

Hello dummy
David Giard

If you don’t like the view engine that ships with MVC, it is possible to replace it with your own. Some open source projects, such as Spark have already given users this ability.

Using the MVC view engine encourages developers to have more control over the output sent to the client and provides a greater separation of concerns for the application as a whole.

Download the code for this sample at MVCDemoView.zip (281.64 KB)

ASP.NET | MVC
Sunday, 04 October 2009 20:38:29 (GMT Daylight Time, UTC+01:00)
# Saturday, 03 October 2009

I am months late producing this video. But now that it's finished, I want to show it off. Earlier this year, my son's 8th grade basketball team tied for the city championship. Here are highlights from the season.

Saturday, 03 October 2009 15:30:23 (GMT Daylight Time, UTC+01:00)
# Friday, 02 October 2009

One of the differences between ASP.NET MVC  and traditional ASP.NET web forms is the URL typed by the user.

In traditional ASP.NET, a URL points to a physical page on disc. Typically one can infer the location of that page by examining the URL. For example, the URL

/Folder1/MyPage.aspx

likely points to a file named MyPage.aspx located in a folder named Folder1.

By contrast, a URL in an ASP.NET MVC application points to an action in a controller. For example, the URL

/Customer/Edit/2

Tells the MVC framework to pass a parameter of "2" to an action method named Edit in a Customer controller class.

ASP.NET MVC (which I’ll call MVC going forward) uses routing to map a URL to a specific action. Routing is typically configured in the  Application_OnStart method of the global.asax file.  An MVC application contains a System.Web.Routing.RouteTable, which contains a collection of routes on which it can act. When you create a new MVC project, a default route is added to this collection by adding the following code in global.asax.

routes.MapRoute(
    "Default",                                              // Route name
    "{controller}/{action}/{id}",                           // URL with parameters
    new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
    );

This code adds a route named "Default" to the route table. This route tells MVC to look for a URL structured similar to the following

Controller/action/id

When it encounters such a URL, it looks for a controller class with a name based on the first part of the URL. By convention, MVC looks for controllers in the "Controllers" folder and is named with the suffix "Controller". So if the first part of the URL is "Customer", MVC will look in the controllers folder for a class derived from System.Web.Mvc.Controller named "CustomerController".

The second part of the URL identifies an action. The action is a method within the controller that returns a  System.Web.Mvc.ActionResult. The ActionResult identifies the view used to render a response (more on that in a later article). So if the second part of the URL is "Edit", MVC will look for a method in the controller class named "Edit" that returns an ActionResult.

The third part of the above URL defines a parameter for the action, in this case a parameter named "id".

The following URL

/Customer/Edit/2

causes MVC to search for a class named Controllers\CustomerController, to call the Edit method in this class and to pass the value 2 to the id parameter of the Edit method.

What if the URL does not contain all three parts? The Default route above specifies a default value for each of the parts. If the third part of the URL is omitted, no parameter is passed to the Action. For a URL with no id parameter, we will need to create an action method that does not expect a parameter. If the second part of the URL is omitted, the default action is "Index", so MVC will look for a method named "Index" in the controller class. If the first part of the URL is omitted, it defaults to "Home" so MVC will look for a Controller class named "HomeController" in the Controllers folder.

You can use this same syntax to add more routes to your application. Simply add more calls to routes.MapRoute() in Global.asax. MVC will match URLs to these routes in the order listed.

Notice that the RouteTable and RouteCollection are part of the System.Web.Routing namespace and not part of any MVC namespace. This should tell you that the routing engine is not restricted to MVC applications. It can be used in any ASP.NET application if you want cleaner URLs.

If you find a URL like /Customer/Edit/2 more asthetically pleasing than /Customers/EditCustomer.aspx?CustID=2, you should investigate the routing engine.

ASP.NET | MVC
Friday, 02 October 2009 14:21:00 (GMT Daylight Time, UTC+01:00)