.Net Lightweight Containers and Plugin Architectures

The following is an excellent resource on Dependency Injection and Dynamic Service Locators in .NET:

http://weblogs.asp.net/cazzu/archive/2004/05/10/129140.aspx

Portrait Of An Agile Development Process

1. What Does It Mean To Run A Project Using An Agile Process?

The term agile refers to a set of patterns and practices that builds a highly collaborative partnership between the business and IT, promotes team communication and delivers functional software releases in iterative cycles. By delivering business value early and often, the process allows for a natural feedback loop to adjust and improve the software.

The difference between an agile process and other processes is that an agile process is crafted to integrate seemlessly into its environment. Rather than dictating rigid process practices that may not apply, the team selects the right process fit for the environment and makes adjustments every iteration, tuning it, to result in an increased team output and quality.

Often agile teams are viewed with skepticism as the methodology is different from traditional approaches. Sometimes there is a misconception that there is a lack of process or that it promotes "cowboy coding". However, a close-up look at an agile team in action reveals a highly structured, iterative development life-cycle flow that is enthusiastically followed by people passionate about delivering value to the business and IT.

2. Basic Terminology

The following are a few terms that describe aspects of the agile patterns and practices:

  • User Stories and Technical Stories – User stories are high level use cases or functionality that describes a deliverable unit of business value. Business analysts provide most of the user stories and the development team provides most of the technical stories.
  • Tasks – Tasks are provided by the development team and are a breakdown of the user story into smaller development chunks. Tasks have an owner and an estimate time assigned. The owner is responsible for tracking actual time against the task to be used later to improve team estimation.
  • Team Velocity – The number of delivered user stories for an iteration measured in estimate time. The team velocity is comprised of the sum of individual velocity.
  • Unit test – Unit tests are automated regression tests built into the code base that test key business logic.

3. Agile Patterns and Practices To Choose From When Crafting Your Process

Upon starting our project, our team crafted an agile process that enabled us to meet the business and IT needs in the time schedule provided. To do this, we integrated many of the agile patterns and practices described below:

A. Establish Iterations and Release Cycles

Iterations are fixed development cycles at the end of which a "deliverable" product is available. The idea is to manage scope so that you don't have half-working code at the end of an iteration. It is important to note that an iteration does not have to result in a production release. A release cycle is managed by the business analysts and technical lead and varies depending on business and IT needs. For our project, the team decided to work on a 3 week iteration cycle, that leaves approximately the last week for the test cycle.

B. Employ a Planning Game To Identify Stories and Tasks

A planning game is the primary tool for the business to drive the process. This meeting kicks off each new iteration and provides an excellent forum for the business, IT and the development team to identify and prioritize user stories and technical stories. Developers provide task and story level estimated time, which allows the business analysts to prioritize and put together a release cycle. At the end of the planning game the development team have their assigned stories and tasks which will be posted to the planning board. These priorities can be adjusted by the business and IT as needs change during the iteration. Typically this is done during the daily standup meeting.

C. Utilize a Daily Standup Meeting to Reinforce Communication

A daily status meeting that lasts about 15 minutes. People are required to stand for the duration, which naturally enforces brevity. Developers provide feedback on tasks they are working on and identify any roadblocks. Business analysts adjust priorities, monitor progress and provide clarification on any business requirement questions. Interested parties or other stakeholders are invited to attend the daily standup meeting and monitor activity. The daily standup meeting for our project occurs at 8:30am and is open for people to monitor.

D. Use a Planning Board to Communicate Task Activity and Ownership

The planning board is a physical poster board that has the stories and tasks affixed as 3x5 cards. When a task is in progress the developer circles it in blue. Upon completion they circle it in green. It is used in the daily standup meeting to visually communicate activity.

E. Identifying and Procuring the Development Tools to Establish a Refactoring Space

It is critical that the right development tools are in place to enable an agile environment. These tools are identified and the environment is setup early on in the project. A refactor space is one in which the development team has all the tools in place to easily modify the entire code base for the project. For example, if an error was identified in a particular approach, the team could fix it across the entire refactoring space. Key tools in the our refactoring space are: Visual Studio.net 2003, Visual Source Safe 6.0d, nunit, nant, funduc (search and replace) and Araxis Merge. These tools enable the team to manage the implementation process efficiently.

F. Establishing an Automated Build, Test, Source Control, Stage and Deploy Process

Automated builds refer to the automation of the many tedious steps involved in building the application components, managing source control, running unit tests and packaging and deploying the application components to the development, test and production environments. This traditionally can be an entire job description all by itself. By automating this process we eliminate a lot of manual work and potential errors due to human error. Our automated build additionally applies a source control label and creates a new versioned directory to a network location containing all files that will be applied for whatever environment is being deployed to (development, test or production). This staging directory provides for a natural rollback code base in addition to an easy location for future reference or trouble shooting!

G. Use Paired Programming Where It Makes Sense on Difficult Tasks

Paired programming simply refers to working collaboratively with another developer to solve a complex problem. Pairing promotes knowledge dissemination in addition to increasing velocity. The more pairing that occurs in a team, the more aware and cross-trained a team becomes, which will increase the team velocity. If a team member gets sick, others can pick up where they left off. That said, there are many tasks that do not require pairing and are best completed individually and in parallel.

H. Promote Collaboration and Shared Code Ownership

It is important in order for a team to collaborate well together to work as a team. Shared code ownership means that we take responsibility for the code as a team and together share its successes and failures. Pairing on complex tasks will help promote this important component of an agile team. You know you're doing it well when everyone on the team feels a personal responsibility to make the best solution and work together to achieve and support it.

I. Use Automated Regression Testing (Unit Tests) Where It Makes Sense

Unit tests are built into the code base to test key business logic and ensure that future enhancements do not introduce errors or break functionality. It is somewhat of an art form to determine where to apply them most effectively. Unit testing for our project is automatically run when doing an automated build to the development environment.

J. Track Team Velocity by Comparing Estimates Vs Actual Task Time

In order to cost the user stories to determine the amount of features that can be developed in an iteration, the business analysts use estimated time provided by the development team. During the iteration the development team tracks the actual time it takes to complete the work. At the end of the iteration the team velocity is how many stories were fully completed, measured with their estimated time. Team velocity tells the business analysts approximately what they can promise to deliver. Comparing the estimate time vs. actual time helps the development team improve their estimates.

K. Follow a Strict Development, Test, Production Environment Deployment Flow

Professionals never work without a safety net. Maintaining clear lines of demarcation between the development, test, and production environments is critical to help ensure the quality of the code base and keep a stable production environment. Our team reinforces these boundaries by using detailed release guides in addition to automated builds that do most of the tedious work.

L. Use Technical Spikes to Gather Information for Unknowns

No technical team knows everything. A technical spike is a very focused research effort on an issue or technology that the team does not have prior knowledge on. It is undertaken to answer a specific business or IT question and usually has a 2 day maximum time limit.


M. Pay Down Your Projects Technical Debt – Increase Your Velocity!

Technical debt is accumulated naturally as projects get more complex. As issues arise the team can’t solve everything and must resort to workarounds for the lower priority issues. As time continues these workarounds take up measurable time in the iteration, decreasing the team velocity. During each iteration find time to pay down some of this technical debt by fixing what you have time for. This will keep your team producing more value and spending less time on other issues.


N. Design Solutions Using Object Oriented, N-Tier, Service-based Architecture Practices

Object Oriented Programming and Ntier development is alive and well. With the advent of .Net many patterns that were previously reserved for C++ are now available for mass consumption with VB.Net and C#. Good architecture is the foundation for delivering a quality, extensible solution. It allows for unit testing and a clear separation of layers that allows the code to evolve and meet the ever growing needs of the business and IT. Separation of key functions into services allows for a powerful distributed architecture that can be leveraged and reused.

O. Refactor Mercilessly to Keep Your Code Base Cruft-Free

Refactoring is improving your code base with new learnings or better implementation practices, such as moving duplicate code to a common base class. Refactoring should occur often, but only when it makes sense, such as when you need to make a change in the area anyway. Without refactoring your code base continues to gather cruft such as duplicate code, non-performant routines and many other issues that result from building new features within a time constraint. This cruft will choke the maintainability, performance, and quality of your application over time in addition to increasing you bug count.

P. Continue to Improve Your Process – Try Something New Every Iteration!

A key aspect of an agile team is to stay agile! Empower your team to continuously look for ways to do what you do more efficiently with better tools or techniques. Encourage them to try something new, as a team, every iteration and roll the things that work well into your process. For example, our team posts digital pictures of whiteboard drawings to Sharepoint and uses Camtasia movies as test scripts for the QA testers. Both practices save measurable time and were the result of trying something new. Another idea would be to track a new team metric for an iteration to see if there is an opportunity to improve team velocity. For example, track the amount of time your team spends building, source controlling, packaging and deploying your solution every release.

4. Our Teams Development Process Overview

This section outlines an overview of the process followed by our team for each iteration.
Iteration Cycle: every three weeks
Release Cycle: determined by business analysts and technical lead

Planning
Planning Game Meeting: [business analysts, development team, stakeholders, interested parties]

  • Business analysts and development team recap previous iteration successes and issues
  • Business analysts identify user stories
  • Development team identifies tasks
  • Development team provides task estimates and those that will require a technical spike
  • Business analysts prioritize user stories based on estimates
  • Development team signs up for tasks using previous iteration velocity as a guide
  • After the meeting the Planning Board is updated to reflect the new iterations story/task owner-ship and activity

Release Planning: [business analysts, technical lead]

  • Determine release date and committed user stories based off estimations and spike feedback
  • Determine if the release will span more that one iteration

Submit Testing Request: [technical lead]

  • Technical lead provides an initiating document that states requirements or what new functionality is being addressed in the iteration
  • Technical lead provides the test plan
  • Technical lead provides the requested testing release date

Submit Production Request: [technical lead]

  • Technical lead provides an initiating document that states requirements or what new functionality is being addressed in the iteration
  • Technical lead identifies rollout team
  • Technical lead submits the production rollback plan
  • Technical lead provides the requested production release date

Implementation

  • Daily Standup Meeting: [business analysts, development team, stakeholders, interested parties]
  • Developers provide task feedback and identify roadblocks
  • Planning Board is updated to reflect activity
  • Business analysts provide updated priorities, requirements and business feedback
  • Stakeholders and interested parties voice concerns or get information regarding activity
  • Developers collaborate on tasks or work independently depending on complexity. Collaboration is encouraged to promote communication and disseminate knowledge.
  • Developers look for opportunities to refactor, apply automated unit tests and reduce project technical debt
  • Automated processes are tuned to keep running smoothly and integrating new manual processes
  • Development team stages build to the development environment often as features are built

Testing Release (Requires IT Approval)

  • Development team provides testing scripts or (Camtasia) movies
  • Development team stages build to the test environment and submits notification to stakeholders
  • Business analysts and Quality Assurance lead coordinate testing effort
  • Business analyst maintains, prioritizes and coordinates issues log
  • Developers resolve issues and stage subsequent test builds to the test environment
  • Technical lead compiles and submits test results to attach to the Production Request
  • Business analysts certify the build as ready for production

Production Release (Requires IT Approval)

Note: Not every iteration may result in a production release. Releases can span multiple iterations. Project production releases occur during a published downtime window.

  • Technical lead sends upcoming release notification to stakeholders
  • Rollout team analyses and reviews the Project Release Guides
  • Review DTS Package Checklist
  • Review Project Production Ready Reports Checklist
  • Review Project Application Updater Release Checklist
  • Review Project Rollout Checklist
  • Review Production Rollback plan
  • Rollout team stages build to the production environment
  • Rollout team tests against new release
  • Business analyst certifies release
  • Rollout team rolls back if release is not certified
  • Technical lead sends successful release notification to stakeholders

5. Summary

The development process used by our team was crafted by selecting a mix of agile patterns and practices that make sense for the environment. Although some of the terminology may seem new, many of these practices have been performed by highly productive, successful development teams in the software industry for years. What the process does is formalize the best of breed practices so that the team can follow a simple structured repetitive pattern, allowing them to focus on what really counts, delivering quality solutions for the business and IT.

Keeping Databases In-Synch With Your Source Control

Problem: Your development, test and production databases tend to accumulate cruft (aka. old stored procedures or schema) and you need a way to manage changes in a simple automated way.

Solution: I've had the great fortune to work with some excellent teams that have crafted elegant solutions to this problem. The following is a boiled down simple approach that provides a great way to tame database source control and upgrade issues.

Development Tools of Choice: VS.Net 2003 Ent., VSS, Nant, SQL Server 2K

Steps:

1. Using VS.Net and VSS, create 2 database projects. One to contain all objects that can be recompiled without data-loss (Stored Procs, UDFs, Views, Triggers). The second database project to contain a database_release.sql file to contain your schema changes for each release (make sure they are repeatable eg. "if exists ....") Use these 2 projects to manage all you database changes from release to release. Be sure to clean up any re-named or deleted objects from VSS.

2. Create an Nant build file that does the following:

  • Allows you to call it with "dev", "test", or "prod"
  • Does a recursive get from VSS on the database projects
  • Applies an auto-revisioned version label to these projects in VSS
  • Stage these files to a well known network location to appropriate sub-directory eg. "dev\AppXDatabase_1.03.22.31"
  • Drops all re-runnable objects from the corresponding target database for dev, test or prod
  • Apply repeatable schema changes for release
  • Recursively apply all the re-runnable objects to the database

3. For each release you can wipe and build the release schema project as needed with new schema for the upcomming release.

Benefits of Approach: By doing this you get a versioned history of changes to your database. You also get versioned stage directories for dev, test and prod environments that have all the schema and re-runnable database objects at that point in time. These versioned stage directories correlate to a label in VSS. By automating the application of the schema and the dropping and recreating of the re-runnable objects your database will reflect your source control.