Ruthlessly Helpful

Stephen Ritchie's offerings of ruthlessly helpful software engineering practices.

Monthly Archives: December 2011

NuGet Kickstart Package

I want to use NuGet to retrieve a set of content files that are needed for the build. For example, the TeamCity build configuration runs a runner.msbuild script, however, that script needs to import a Targets file, like this:

<Import Condition="$(BuildPath)\ImportTargets\MSBuild.Lender.Common.Targets"
        Project="$(BuildPath)\ImportTargets\MSBuild.Lender.Common.Targets"
        />

The plan is to create a local NuGet feed that has all the prerequisite files for the build script. Using the local NuGet feed, install the “global build” package as the first build task. After that, the primary build script can find the import file and proceed normally. Here is the basic solution strategy that I came up with.

To see an example, follow these steps:

1. Create a local NuGet feed. Read more information here: http://docs.nuget.org/docs/creating-packages/hosting-your-own-nuget-feeds

2. Write a NuGet spec file and name it Lender.Build.nuspec. This is simply an XML file. The schema is described here: http://docs.nuget.org/docs/reference/nuspec-reference

<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
  <metadata>
    <id>_globalBuild</id>
    <version>1.0.0</version>
    <authors>Lender Development</authors>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>Lender Build</description>
  </metadata>
  <files>
    <file src="ImportTargets\**" target="ImportTargets" />
  </files>
</package>

Notice the “file” element. It specifies the source files, which includes in the MSBuild.Lender.Common.Targets file when the ImportTargets folder is added.

3. Using the NuGet Package Explorer, I opened the Lender.Build.nuspec file and saved the package in the LocalNuGetFeed folder. Here’s how that looks:

NuGet_Package_Explorer_1211-12-21

4. Save the package to the local NuGet feeds folder. In this case, it is the C:\LocalNuGetFeeds folder.

5. Now let’s move on over to where this “_globalBuild” dependency is going to be used. For example, the C:\projects\Lender.Slos folder.  In that folder, create a packages.config file and add it to version control. That config file looks like this:

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="_globalBuild" version="1.0.0" />
</packages>

This references the package with the id of “_globalBuild”, which is found in the LocalNuGetFeeds package. It is one of the available package sources because it was added through Visual Studio, under Tools >> Library Package Manager >> Package Manager Settings.

Library_Package_Manager_settings_2011-12-21

6. From MSBuild, the CI server calls the “Kickstart” target before running the default script target. The Kickstart target uses the NuGet.exe command line to install the global build package. Here is the MSBuild script:

<Project DefaultTargets="Default"
         xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
         ToolsVersion="4.0"
         >
  <PropertyGroup>
    <RootPath>.</RootPath>
    <BuildPath>$(RootPath)\_globalBuild.1.0.0\ImportTargets</BuildPath>
    <CommonImportFile>$(BuildPath)\MSBuild.Lender.Common.Targets</CommonImportFile>
  </PropertyGroup>

  <Import Condition="Exists('$(CommonImportFile)')"
          Project="$(CommonImportFile)"
          />

  <Target Name="Kickstart" >
    <PropertyGroup>
      <PackagesConfigFile>packages.config</PackagesConfigFile>
      <ReferencesPath>.</ReferencesPath>
    </PropertyGroup>
    <Exec Command="$(NuGetRoot)\nuget.exe i $(PackagesConfigFile) -o $(ReferencesPath)" />
  </Target>

  <!-- The Rebuild or other targets belong here -->
  <Target Name="Default" >
    <PropertyGroup>
      <ProjectFullName Condition="$(ProjectFullName)==''">(undefined)</ProjectFullName>
    </PropertyGroup>

    <Message Text="Project name: '$(ProjectFullName)'"
             Importance="High"
             />
  </Target>

</Project>

7. In this way, the MSBuild script uses NuGet to bring down the ImportTargets files and places them under the _globalBuild.1.0.0 folder. This can happen on the CI server with multiple build steps. For the sake of simplicity here are the lines in a batch file that simulates these steps:

%MSBuildRoot%\msbuild.exe "runner.msbuild" /t:Kickstart
%MSBuildRoot%\msbuild.exe "runner.msbuild"

With the kickstart bringing down the prerequisite files, the rest of the build script performs the automated build using the common Targets properly imported.

Advertisement

Pro .NET Best Practices: Overview

For those who would like an overview of Pro .NET Best Practices, here’s a rundown on the book.

The book presents each topic by keeping in mind two objectives:  to provide reasonable breath and to go into depth on key practices. For example, the chapter on code analysis looks at both static and dynamic analysis, and it goes into depth with FxCop and StyleCop. The goal is to strike the balance between covering all the topics, discussing the widely-used tools and technologies, and having a reasonable chapter length.

Chapters 1 through 5 are focused on the context of new and different practices. Since adopting better practices is an initiative, it is important to know what practices to prioritize and where to uncover better practices within your organization and current circumstances.

Chapter 1: Ruthlessly Helpful

This chapter shows how to choose new and different practices that are better practices for you, your team, and your organization.

  • Practice Selection
    • Practicable
    • Generally Accepted and Widely Used
    • Valuable
    • Archetypal
  • Target Areas for Improvement
    • Delivery
    • Quality
    • Relationships
  • Overall Improvement
    • Balance
    • Renewal
    • Sustainability
  • Summary

Chapter 2: NET Practice Area

This chapter draws out ways to uncover better practices in the areas of .NET and general software development that provide an opportunity to discover or learn and apply better practices.

  • Internal Sources
    • Technical Debt
    • Defect Tracking System
    • Retrospective Analysis
    • Prospective Analysis
  • Application Lifecycle Management
  • Patterns and Guidance
    • Framework Design Guidelines
    • Microsoft PnP Group
    • Presentation Layer Design Patterns
    • Object-to-Object Mapping
    • Dependency Injection
  • Research and Development
    • Automated Test Generation
    • Code Contracts
  • Microsoft Security Development Lifecycle
  • Summary

Chapter 3: Achieving Desired Results

This chapter presents practical advice on how to get team members to collaborate with each other and work toward a common purpose.

  • Success Conditions
    • Project Inception
    • Out of Scope
    • Diversions and Distractions
    • The Learning/Doing Balance
  • Common Understanding
    • Wireframe Diagrams
    • Documented Architecture
    • Report Mockups
    • Detailed Examples
    • Build an Archetype
  • Desired Result
    • Deliverables
    • Positive Outcomes
    • Trends
  • Summary

Chapter 4: Quantifying Value

This chapter describes specific practices to help with quantifying the value of adopting better development practices.

  • Value
    • Financial Benefits
    • Improving Manageability
    • Increasing Quality Attributes
    • More Effectiveness
  • Sources of Data
    • Quantitative Data
    • Qualitative Data
    • Anecdotal Evidence
  • Summary

Chapter 5: Strategy

This chapter provides you with practices to help you focus on strategy and the strategic implications of current practices.

  • Awareness
    • Brainstorming
    • Planning
    • Monitoring
    • Communication
  • Personal Process
    • Commitment to Excellence
    • Virtuous Discipline
    • Effort and Perseverance
  • Leverage
    • Automation
    • Alert System
    • Experience and Expertise
  • Summary

Chapters 6 through 9 are focused on a developer’s individual practices. These chapters discuss guidelines and conventions to follow, effective approaches, and tips and tricks that are worth knowing. The overarching theme is that each developer helps the whole team succeed by being a more effective developer.

Chapter 6: .NET Rules and Regulations

This chapter helps sort out the generalized statements, principles, practices, and procedures that best serve as .NET rules and regulations that support effective and innovative development.

  • Coding Standards and Guidelines
    • Sources
    • Exceptions
    • Disposable Pattern
    • Miscellaneous
  • Code Smells
    • Comments
    • Way Too Complicated
    • Unused, Unreachable, and Dead Code
  • Summary

Chapter 7: Powerful C# Constructs

This chapter is an informal review of the C# language’s power both to harness its own strengths and to recognize that effective development is a key part of following .NET practices.

  • Extension Methods
  • Implicitly Typed Local Variables
  • Nullable Types
  • The Null-Coalescing Operator
  • Optional Parameters
  • Generics
  • LINQ
  • Summary

Chapter 8: Automated Testing

This chapter describes many specific practices to improve test code, consistent with the principles behind effective development and automated testing.

  • Case Study
  • Brownfield Applications
  • Greenfield Applications
  • Automated Testing Groundwork
  • Test Code Maintainability
    • Naming Convention
    • The Test Method Body
  • Unit Testing
    • Boundary Analysis
    • Invalid Arguments
    • Invalid Preconditions
  • Fakes, Stubs, and Mocks
    • Isolating Code-Under-Test
    • Testing Dependency Interaction
  • Surface Testing
  • Automated Integration Testing
  • Database Considerations
  • Summary

Chapter 9: Build Automation

This chapter discusses using build automation to remove error-prone steps, to establish repeatability and consistency, and to improve the build and deployment processes.

  • Build Tools
    • MSBuild Fundamentals
    • Tasks and Targets
    • PropertyGroup and ItemGroup
    • Basic Tasks
  • Logging
  • Parameters and Variables
  • Libraries and Extensions
  • Import and Include
  • Inline Tasks
  • Common Tasks
    • Date and Time
    • Assembly Info
    • XML Peek and Poke
    • Zip Archive
  • Automated Deployment
    • Build Once, Deploy Many
    • Packaging Tools
    • Deployment Tools
  • Summary

Chapters 10 through 12 are focused on supporting tools, products, and technologies. These chapters describe the purpose of various tool sets and present some recommendations on applications and products worth evaluating.

Chapter 10: Continuous Integration

This chapter presents the continuous integration lifecycle with a description of the steps involved within each of the processes. Through effective continuous integration practices, the project can save time, improve team effectiveness, and provide early detection of problems.

  • Case Study
  • The CI Server
    • CruiseControl.NET
    • Jenkins
    • TeamCity
    • Team Foundation Server
  • CI Lifecycle
    • Rebuilding
    • Unit Testing
    • Analysis
    • Packaging
    • Deployment
    • Stability Testing
    • Generate Reports
  • Summary

Chapter 11: Code Analysis

This chapter provides an overview of many static and dynamic tools, technologies, and approaches with an emphasis on improvements that provide continuous, automated monitoring.

  • Case Study
  • Static Analysis
    • Assembly Analysis
    • Source Analysis
    • Architecture and Design
    • Code Metrics
    • Quality Assurance Metrics
  • Dynamic Analysis
    • Code Coverage
    • Performance Profiling
    • Query Profiling
    • Logging
  • Summary

Chapter 12: Test Framework

Chapter 12 is a comprehensive list of testing frameworks and tools with a blend of commercial and open-source alternatives.

  • Unit Testing Frameworks
  • Test Runners
    • NUnit GUI and Console Runners
    • ReSharper Test Runner
    • Visual Studio Test Runner
    • Gallio Test Runner
    • xUnit.net Test Runner
  • XUnit Test Pattern
    • Identifying the Test Method
    • Identifying the Test Class and Fixture
    • Assertions
  • Mock Object Frameworks
    • Dynamic Fake Objects with Rhino Mocks
    • Test in Isolation with Moles
  • Database Testing Frameworks
  • User Interface Testing Frameworks
    • Web Application Test Frameworks
    • Windows Forms and Other UI Test Frameworks
  • Acceptance Testing Frameworks
    • Testing with Specifications and Behaviors
    • Business-Logic Acceptance Testing
  • Summary

Chapter 13: Aversions and Biases

The final chapter is about the aversions and biases that keep many individuals, teams, and organizations from adopting better practices. You may face someone’s reluctance to accept or acknowledge a new or different practice as potentially better. You may struggle against another’s tendency to hold a particular view of a new or different practice that undercuts and weakens its potential. Many people resist change even if it is for the better. This chapter helps you understand how aversions and biases impact change so that you can identify them, cope with them, and hopefully manage them.

  • Group-Serving Bias
  • Rosy Retrospection
  • Group-Individual Appraisal
  • Status Quo and System Justification
  • Illusory Superiority
  • Dunning-Kruger Effect
  • Ostrich Effect
  • Gambler’s Fallacy
  • Ambiguity Effect
  • Focusing Effect
  • Hyperbolic Discounting
  • Normalcy Bias
  • Summary

Why a Book on .NET Best Practices?

I am a Microsoft .NET software developer. That explains why the book is about .NET best practices. That’s in my wheelhouse.

The more relevant question is, why a book about best practices?

When it comes right down to it, many best practices are the application of common sense approaches. However, there is something that blocks us from making the relatively simple changes in work habits that produce significant, positive results. I wanted to further explore that quandary. Unfortunately, common sense is not always common practice.

There is a gap between the reality that projects live with and the vision that the team members have for their processes and practices. They envision new and different practices that would likely yield better outcomes for their project. Yet, the project reality is slow to move or simply never moves toward the vision.

Tension between reality and vision

Tension between reality and vision

Many developers are discouraged by the simple fact that far too many projects compromise the vision instead of changing the reality. These two concepts are usually in tension. That tension is a source of great frustration and cynicism. I wanted to let people know that their project reality is not an immovable object, and the team members can be an irresistible force.

Part of moving your reality toward your vision is getting a handle on the barriers and objections and working to overcome them. Some of them are external to the team while others are internal to the team. I wanted to relate organizational behavior to following .NET best practices and to software development.

Knowledge

The team must know what to do. They need to know about the systematic approaches that help the individual and the team achieve the desired results. There are key practice areas that yield many benefits:

  • Automated builds
  • Automated testing
  • Continuous integration and delivery
  • Code analysis
  • Automated deployment

Of course, there is a lot of overlap in these areas. The management scientist might call that synergy. A common theme to these practice areas is the principle of automation. By acquiring knowledge in these practice areas you find ways to:

  • Reduce human error
  • Increase reliability and predictability
  • Raise productivity and efficiency

Know-how in these practice areas also raises awareness and understanding, creates an early warning system, and provides various stakeholders with a new level of visibility into the project’s progress. I wanted the reader to appreciate the significance and inter-relatedness of these key practice areas and the benefits each offers.

Skill

The team needs to know how to do it. Every new and different practice has a learning curve. Climbing that curve takes time and practice. The journey from newbie to expert has to be nurtured. There are no shortcuts that can sidestep the crawl-walk-run progression. Becoming skilled requires experience. Prototyping and building an archetype are two great ways to develop a skill. Code samples and structured walkthroughs are other ways to develop a skill. I wanted the book to offer an eclectic assortment of case studies, walkthroughs, and code samples.

Attitude

Team members must want to adopt better practices. Managers need to know why the changes are for the better, in terms managers can appreciate. The bottom line, it is important to be able to quantify the benefits of following new and different practices. It is also important to understand what motivates and what doesn’t. It helps to understand human biases. Appreciate the underlying principle that software projects are materially impacted by how well individuals interact. I wanted to highlight and communicate the best practices that relate to the human factors that include persuasion, motivation, and commitment.

Pro .NET Best Practices

Here are the links to Pro .NET Best Practices:

Apress: http://www.apress.com/9781430240235

Amazon: http://www.amazon.com/NET-Best-Practices-Stephen-Ritchie/dp/1430240237

Barnes and Noble: http://www.barnesandnoble.com/w/pro-net-best-practices-stephen-d-ritchie/1104143991

Cover of the book Pro .NET Best Practices