Home

Archived Posts from “Recommended”

.NET Podcast Recommendations

06

August

Last Friday, a fellow coder asked the team for podcast recommendations.  Since I listen to anywhere from 6-10 podcasts a week, I was happy to share what is currently in my top podcast rotation. 

It is worth noting that those of us in the .NET community are rather fortunate as there are a number of recent newcomers in this space.  In fact, four of my top six podcasts have been around for less than 4 months.  I personally think they’ve all done a standup job and it has been enjoyable listening to the podcasts as they mature.  Maybe some day, years from now, young developers will gather around as I tell tales of the very first Herding Code podcast. You never know…

Enough with the intro already.  Here’s my .NET Podcast Recommendation List in no particular order (other than alphabetical):

Alt.NET Podcast
http://altnetpodcast.com/
Hosted by Mike Moore
Currently on Episode 8 

Deep Fried Bytes
http://deepfriedbytes.com/
Hosted by Keith Elder and Chris Woodruff
Currently on Episode 8

Hanselminutes 
http://www.hanselminutes.com/
Hosted by Scott Hanselman
Currently on Show #124 

Herding Code
http://herdingcode.com/
Hosted by Jon Galloway, K. Scott Allen, Kevin Dente and Scott Koon
Currently on Episode 11

.NET Rocks!
http://www.dotnetrocks.com/
Hosted by Carl Franklin and Richard Campbell
Currently on Show #365

Stackoverflow
http://blog.stackoverflow.com/
Hosted by Jeff Atwood and Joel Spolsky
Currently on Podcast #16

kick it on DotNetKicks.com


Compile Help File Documentation Using Sandcastle

05

August

I am currently on the bench at work waiting for my next assignment to start up in a few days.  Rather than sitSandcastle Logo around, read blogs and listen to podcasts, I’m keeping myself busy by putting together the beginnings of a code library to be shared across our development team.  Yesterday I started the foundation.  I defined the framework, file system layout and basic namespace conventions.  I also created two class libraries and associated test projects to get the ball rolling.  I’m pleased with the way the common library is turning out.

Today, I refactored a bit and then focused on documentation.  Specifically, I generated help file documentation via the XMLSummary comments. I searched around and played with various utilities and ultimately decided on Sandcastle and Sandcastle Help File Builder.

Sandcastle.jpgSandcastle - Documentation Compiler for Managed Class Libraries, created by Microsoft, produces accurate, MSDN style, comprehensive documentation by reflecting over the source assemblies and optionally integrating XML Documentation Comments. Sandcastle works with or without authored comments and supports .NET Framework 1.1, 2.0, 3.0 and 3.5.  Sandcastle is, however, a command line based tool which has no GUI front-end.  That’s where Sandcastle Help File Builder (SCHB) comes in.  SCHB provides a user interface (as well as command line based tools) to facilitate the building of help files in an automated fashion. Both applications may be found on Codeplex.

Sandcastle (really Sandcastle Help File Builder wrapped around Sandcastle) is easy to install and navigate and I was able to quickly integrate into the common libraries’ best practices.  Now when additional code (new library, class, method, etc) is appended to our common code repository, team members simply need to follow the overall folder structure, code library templates/namespaces and update the Help File Builder project which is now in place. 

Below are the instructions on how to extend the existing Help File Builder project.  These instructions will be share with my team members though they can easily be altered to create a help file from the ground up:

  1. Download and install Sandcastle and Sandcastle Help File Builder from Codeplex.

  2. Apply XML comments to your code base. 
  3. Navigate to the Build Tab of your project’s properties and do the following:
    • Check XML documentation file
    • Set file name to bin\[mode]\assembly name.xml where [mode] is debug or release. Example: bin\release\MyCompany.Common.Serialization.xml
  4. Compile your assemblies in release mode.   Note: I’m opting to only generate documentation per the assemblies/xml generated in release mode although it doesn’t have to be this way.
  5. Run Sandcastle Help File Builder. The existing Sandcastle Help File Builder project can be found in the following location: MyCompany\Common\MyCompany.Common.shfb
  6. Add your compiled assembly to the SCHB project:
    • Click Add > Browse to the libraries’ bin\Release > Select dll
    • After the assembly is added, the dll and xml files will be listed in the ‘Assemblies to Document’ list box. 
  7. Document the assembly’s namespace by clicking on the ‘Namespaces’ button and editing the summary.
  8. The MyCompany.Common.shfb project is already configured so there’s no need to change any of the project properties. For future reference, all non-default values are highlighted in bold font within the property list. This information is most obvious if you toggle the project properties to display Alphabetically rather than Categorized.

    Here’s a list of the settings which have been updated:

    • Help Title=MyCompany.Common Class Library
    • HtmlHelpName=MyCompany.Common
    • KeepLogFile=False
    • OutputPath=./
    • PresentationStyle=vs2005
    • SdkLinkType=Index
  9. Generate the help file by clicking the Generate button in the toolbar.
  10. View the help file by double-clicking the MyCompany/common/MyCompany.Common.chm or by opening the file via the SCHB Documentation/View help file menu option.

Again, I found the tools easy to use though I did encounter one gotcha. My file path included a folder named ".NET 3.5".  I found that Help File Builder didn’t like the naming convention.  Apparently the preceding "." caused the issue.  Once I renamed the folder to "NET 3.5" everything worked like a charm.

 

kick it on DotNetKicks.com

References:


Analyzing Your .NET Code with NDepend

30

July

NDepend is a static analyzer that simplifies the management of a complex .NET code base. Architects and developers can analyze code structure, specify design rules, plan massive refactoring, do effective code reviews and compare different versions of the code. The result is better communication, improved quality, easier maintenance and faster development.  Sounds good, eh?

Full disclosure: I received a free pro version of the NDepend from Patrick Smacchia last week along with little encouragement to use the tool and buzz about it if I find it useful.  Patrick’s timing, in fact, could not have been better as just the evening before a colleague of mine was asking for code metric tool recommendations.  Hopefully the review represents me well, but I am thrilled with NDepend and recommend it highly to anyone wanting to get "more familiar" with their code.

As published by Patrick Smacchia

…something difficult in promoting a tool such as NDepend is to educate about what it can bring to your development shop in terms of agility. NDepend comes with a set of innovative features currently not supported by any other .NET tool. I like to think that what tools such as ReSharper or CodeRush are doing to your code at micro level (i.e methods’ body structuring), NDepend does it at macro level (i.e class, namespace, assembly structuring). Hence, as a developer I personally use both kind of tools to automatically control every aspects of the code base I am working on…

Being a big fan of ReSharper, I had high hopes for NDepend.  Knowing my co-worker could use some help finding a good code analyzer and having a free copy of the software dropped in my lap, I had the immediate incentive to dig into the NDepend tool kit…

How to Get Started

Since I wasn’t all too familiar with NDepend, I opted to first gather basic information about the tool and capabilities.  Here’s what I did:

1. I watched two online demos: Getting started and VisualNDepend basics

2. I reviewed three online tutorials: How do I analyze my .NET applications using NDepend?, What does the NDepend report tell me about my code? and I want to go further to have a better control over my code

3. I read a recent NDepend review posted by Andre Loker and previewed Patrick Smacchia’s Blog for his latest comments.

First Impressions

Before even opening the software it was very clear that NDepend was super powerful and, as another colleague of mine recently said, "it can be a mind blower."  As I am very sensitive to informatiimageon overload, I proceeded simply and cautiously by basically following the steps found in the online demos.  The Visual NDepend 2.9.0 IDE is friendly and somewhat familiar as the start page could be compared to that of Visual Studio.  Here you may create/open projects or analyze/compare assemblies using the provided shortcuts.  Additionally, you are presented with quick links to the online demos and the installers for NDepend Visual Studio and Reflector add-ins. 

imageI opted to analyze a set of assemblies.  After selecting a half dozen assemblies managed within my current application, the assembly analysis is run and then, after a few moments, the results are presented within the VisualNDepend UI. 

Remember my earlier comment about being sensitive to information overload?  Well, if I wasn’t ready for it, the tool’s default display may have knocked me off my seat.  As you can see in the accompanying screen shot, there are many views and the UI is quite busy.  For the experienced user this is great as the numerous windows actually work nicely together.  For a new user, in my opinion, the elaborate UI may be inappropriate — possibly intimidating — especially if the new user really only wants to gather a simple metric like how many lines of code (LOC) make up a specific component.

With this said, the UI can be customized and all the information is very useful once you understand it.  Don’t be intimidated by NDepend even though the first impression can be a "mind blower."

I clicked around the UI for about 30 minutes and I quickly got a good sense of its power.  Certainly the demos, tutorials and blogs noted above helped lessen my learning curve so I encourage you to follow my footsteps.

Code Query Language (CQL)

What impressed me most about the NDepend is its Code Query Language (CQL).  Per the NDepend site:

NDepend considers your code as a database and you can write some CQL statements to query and check some assertions on this database.

Out-of-the-box, NDepend comes with dozens of queries which fall into varying categories from Code Quality to Test Coverage .NET Framework Usage. 

And NDepend provides the same 82 code metrics to support you in building your own queries!   Here are a few simple examples of what you can do with the CQL:image

1. Which public methods have more than 30 lines of code?
SELECT METHODS WHERE NbLinesOfCode > 30 AND IsPublic

2. Which classes implement System.IDisposable?
SELECT TYPES WHERE IsClass AND Implements "System.IDisposable"

3. Which methods have been refactored recently and is not thoroughly covered by tests?
SELECT METHODS WHERE CodeWasChanged AND PercentageCoverage < 100

On top of that you can enable/disable or even edit the out-of-the-box queries.  For example, if you don’t agree that all static fields should be prefixed with an ’s_’ change the query to validate your standard or remove the check all together.

With the Code Query Language, the sky is the limit.  Did I mention the editor comes with Intellisense?

Reports

Go ahead and generate a report.  Check out this example which gives you a run down of the application and assembly metrics, an assembly dependency diagram, CQL Queries and Constraints and much more.  Whereas the VisualNDepend UI is geared toward the architect or lead developer type who is wanting to really dig into an application, the report seems to be more suitable for a less technical audience.  Perhaps the report could be used as part of an executive summary or could complement a developer’s code review.  Simply, it is a professional output (HTML only, I think) consisting of endless information and even pictures. 

Integration

Very quickly I wanted to call out that NDepend integrates not only with VisualStudio and Reflector but also MSBuild, NAnt, and CruiseControl.NET.  I personally think it is great that NDepend was implemented in a manner in which its frequent (read: continuous) and easy (read: automated) use is promoted.  Well done.

Final Thoughts

NDepend is darn impressive. It is a "mind blower" if you will.  NDepend provides more than ample metrics, a flexible (albeit busy) UI, a customizable query language, professional reports and hooks into applications like Visual Studio and Reflector along with support for processes like automated builds and continuous integration.  If you really want to know your code and you are looking for a tool which provides more than simple application metrics, NDepend may be the right product for you.  I highly suggest you check it out.

kick it on DotNetKicks.com


SQL Tip: Uniquely Name Table Columns

10

June

It is easy to see the subtle difference between the Product Tables below.  The table to the left adds the table name as a prefix to nearly all of the column names. image The table on the right represents very simple column names with no redundancy.  Early in my career, I preferred the implementation to the right as I felt this pattern best represented the object (table) itself.  After all, we all have a name.  We don’t have a PersonName. Well, it didn’t take me long to change my opinion.

The next time you are designing a database, do yourself a favor and mimic the pattern to the left.  Always prefix column names with the table name if the column name is likely to be repeated  in more than one table.  ID, Name, Description, DateAdd and DateChange are good examples of column names which tend to show up in multiple places.  When it comes time to build your queries and work with the result sets, you will thank me. 

Consider the two following routines — each returns the same result but the latter is much cleaner, readable, consists of less code and is inherently greater resistant to stupid coding errors especially within the syntax of the join and the column aliases.

– Poor implementation
declare @Product table
(
    ID int, Name varchar(50)
)

declare @ProductVersion table
(
    ID int, ProductID int, VersionNumber int
)

insert into @Product(ID, Name)
select 1, ‘product 1′
union
select 2, ‘product 2′

insert into @ProductVersion (ID, ProductID, VersionNumber)
select 1, 1, 1
union
select 1, 2, 1

– Note the column aliases and
– join on less-than-obvious columns
select P.ID as ProductID, PV.ID as ProductVersionID from
@Product P inner join
@ProductVersion PV on (P.ID = PV.ProductID)

go

– Proper implementation
declare @Product table
(
    ProductID int, Name varchar(50)
)

declare @ProductVersion table
(
    ProductVersionID int, ProductID int, VersionNumber int
)

insert into @Product(ProductID, Name)
select 1, ‘product 1′
union
select 2, ‘product 2′

insert into @ProductVersion (ProductVersionID, ProductID, VersionNumber)
select 1, 1, 1
union
select 1, 2, 1

– Note there’s no need for aliases and
– the join obvious
select P.ProductID, PV.ProductVersionID from
@Product P inner join
@ProductVersion PV on (P.ProductID = PV.ProductID)

Keep this tip in mind.  It will save you heartache throughout your next project.

kick it on DotNetKicks.com


Somewhat Timely iPhone Review

10

June

With Apple’s 3G, "twice as fast, half the price" 2.0 iPhone Release announcement yesterday, I think we’re all ripe to read yet another iPhone review before the new devices go on sale in the US on July 11. 

imageFull-disclosed: I proudly sported a company Blackberry for three years prior to picking up an iPhone about four months ago. In all sincerity, turning in my Blackberry was one of the most difficult things about leaving my last job. It felt like I was losing my best friend or being forced to involuntarily kick a habit.  Now, I ask you, is there Life after Blackberry?

I do nearly everything based on the recommendation of others.  Hence, I interviewed a lot of folks which I considered "into gadgets" and asked them which phone they would recommend to a poor old sob who just lost his best friend.  Not so surprisingly, nearly everyone said, "You should get my phone" and then they would show off their personal phone-of-the-year award winner.  All Blackberry owners recommended Blackberries.  All iPhone owners recommended iPhones.  Blackberry owners were more than happy to share the short-comings of the iPhone but their more-than-likely jealous attempts to belittle the iPhone couldn’t compete with the true excitement on the faces of those who demonstrated to me exactly what the iPhone could do.   Since there were far goofy-in-love iPhone owners than bitter Blackberry owners in the office, I purchased the 16GB iPhone as a leap of faith since I was still, in my mind, a bitter Blackberry owner/lover.

My first experience was "WTF?"  I told the sales person at the Apple Store I would like to purchase a nearly $500 iPhone.  I think they said "cool," scanned the box, scanned my credit card using a handheld device in the middle of a crowed store and asked if they "could email me the receipt."  As technically paperless as I may be, I reluctantly said "yes" and started walking out of the store with my shiny new phone and no tangible proof of purchase.  I didn’t get too far until I remembered I was first-and-foremost buying a phone — a phone which needs an account and phone number.  I asked the sales person where I set this up and nicely enough they said, "Download iTunes.  Plug in the iPhone.  Follow the instructions.  It’s easy."  Truth be told, I left the store feeling a little off guard yet excited (WTF) and wondered if my Mom would be able to handle the same experience.

I got back to the office, downloaded the latest version of iTunes, plugged in the iPhone and experience was simply magical.  I receive a confirmation text message along with my new phone number within 10 minutes.  The AT&T account activation was super smooth and honestly very, very fun mostly because it worked differently than any other cell phone signup and without a hitch.  Mom would have been excite (and relieved) too.

The iPhone took some getting used to.  I suspect the reason is simple.  For a Blackberry user, an iPhone is a toy and a Blackberry is a professional tool.  I am still not completely over this fact.  Now having spent 4 months with my new toy, I still keep my iPhone hidden in my briefcase when meeting with clients.  In my former Blackberry life, I would "wear" my buzzing and blinking Blackberry like a badge of honor almost always.

All told, I am very happy with my purchase.  The iPhone rocks primarily due to all of the bells and whistles.  A guy like me that doesn’t read the manual is continuously surprised and amused by each newly discovered feature such as music fading out when a call comes in and then fading back in once the call is over or the eye glass which magnifies and helps navigate email text.  

But, remember, again, the iPhone is a toy.  It is not a business tool.  My biggest gripes (in no particular order):

  1. No support for Exchange (Provided with next release.)
  2. Email Auto-Check can be configured no more frequently than every 15 minutes. (I bet this issue goes away with Exchange support.)
  3. No green light / red light to indicate a new message, text, missed call, etc.  (This is probably a nice to have for some.  This is the #1 Blackberry feature which I miss.  Even more than increasing the email auto-check frequency.)
  4. No copy and paste support (NOT provided with the next release)
  5. No "Multi-Select" functionality (All new and existing iPhones will be updated with some iPhone 2.0 multi-select functionality on 7/11.)
  6. Leave the phone in the sun and the metal gets hots — really F’ing hot.
  7. There’s a giant YouTube quick launch button on the Home Screen yet there’s no built in To Do List application.  
  8. I’m still not used to the keypad.  I will never ever be as efficient with the iPhone keypad as I was with the raised Blackberry keyboard.  Actually, I am willing to bet no one will be.  I have found that holding the phone in my right hand while typing with my left pointer finger and right thumb provides the best results.  (I’m a lefty.  Right-handed folks may need to alternate hands and fingers accordingly.)
  9. This isn’t a knock on the iPhone, but AT&T coverage simply isn’t as good as Verizon provided for my Blackberry.  The whole AT&T/iPhone monopoly kind of bugs me although I understand AT&T is in cahoots with (read: subsidizing) Apple to reduce the purchase price of the next version of the iPhone.  This may, I understand, increase the price of the data plan, however.  My source. image

You undoubtedly noticed that most of my gripes are based on my own personal preferences per on my past Blackberry experience or are being addressed with the new iPhone 2.0 release.  Apple is addressing the toy vs tool issue with the introduction of "several significant enhancements," including:

  • 3G broadband wireless connectivity, which gives customers a home broadband-like speed experience when surfing the Internet, sharing files, and using media-rich Web applications
  • Business-class capabilities, including e-mail, viewed on a large, touch-screen device and designed to meet the needs of companies of all sizes
  • The ability for developers, including AT&T, to create customized consumer and business applications using the Apple software developer’s kit (SDK). 

Though the phone is intuitive (nearly everyone who plays with my iPhone figures it out), I suggest reading the manual unless you like surprises like I do.  Each day I find something new like the phone silence button or figuring out how to reboot the device. Yes, the phone has locked up on me twice when quickly switching between programs (but even the reboot is cool) and my browser session will be interrupted and I’m occasionally brought back to the Home Screen unexpectedly.  (This doesn’t happen enough to be a gripe.)image

I know some folks were/are concerned with the price of the data plan.  My current data plan is $20/month for a total cost of $60/month.  I didn’t do a lot of shopping around but I’m not unhappy with this rate.  In my opinion it is currently reason, but as I mentioned previously the rate may be going up to subsidize the cost of the phone itself.

Since I provided my biggest (perhaps only) gripes, it is only fair to list my favorite features.  Note, this list really only scratches the surfaces as "yesterday’s" unbelievable feature are now customary and assumed:

  1. Magical Account Activation
  2. Visual Voice Mail
  3. Multiple Email Account Support
  4. Bells and Whistles like Music Fade and Text Magnification
  5. Wireless Connection Detection makes me want to pursue Wardriving as a hobby.
  6. All-in-one-always-there-ness.  I’ve listened to more music, audio books and podcasts in the last 4 months simply because my iPod is simply always with me.  I use the Maps and the Camera far more often than I anticipated and the Safari Browser has been used to put more than one lunch debate to rest.
  7. Silly, but I love the fact that this phone can’t be turned on accidentally.  The "Slide to unload" function is genius.
  8. Horizontal/vertical orientation display.  When I first saw this on the commercials, I didn’t think think it was real.

What’s next?  Well, I am not crying over buying my iPhone 5 months before the 3G     release and a significant price cut.  I will definitely consider upgrading in July for the 3x browsing speeds and GPS though.  My fingers will be very loosely crossed that existing customer rebates will come in some form.  This isn’t unprecedented.  I would like to play around with iPhone application development a bit, but it is pretty low on my Task List — especially since the iPhone doesn’t have a Task List.  

I don’t think I talked the iPhone up enough in the post, but I believe it is my honest opinion.  With the decreased purchase price and added "business features," I think the iPhone is a steal come July.  The phone+ gets my recommendation.

Let me know if you have any questions.

kick it on DotNetKicks.com


It’s Time to Change Your Visual Studio Theme

08

June

I started using the TextMate Theme for Visual Studio a week ago.  This afternoon I switched back to the default VS theme and nearly threw up. It’s really flipping plain to the point of being ugly. All the same, I looked at the white screen for less than a minute and I reinstalled TextMate.  I didn’t even strike a key.  I just rolled back.  I guess the default theme is no longer my default theme.image

I have never used an alternate theme before. In fact, not too long ago, I used to resent looking at code which wasn’t being shown under the default (read: most common) theme. I have gone as far as to ask developers to read their code to me (you know who you are) because their theme was too busy and/or simply didn’t agree with me.  Unfamiliar themes are a distraction — at least they are to me.  In my opinion, all presentations (code reviews included) should be done using the default theme as to not take away from the information being presented.

Coincidentally, it took me a couple of hours to get used to the TextMate theme. I suppose having watched all of the MVC Storefront presentations which use TextMate rather than the default theme (oh, the irony) instigated and most likely helped me with the transition.

It is quick and easy to switch between themes (Tools > Import and Export Settings…).  Even if you are sharing your code or presenting often, I would encourage you to sample something new.  If you are like me, you may find an alternate theme gives your code some personality, possibly provides a little creative inspiration or simply lessens the strain on your eyes (I know the default white background can get a little blurry for me at the end of the day.) 

Give an alternate theme a try and let me know what you think.

kick it on DotNetKicks.com


ReSharper 4.0 Beta Makes Me Giggle

31

May

Today I did what I should have done a lot while ago.  I watched the Jedi Coding Demo and installed JetBrain’s ReSharper - The Most Intelligent Add-In To Visual Studio about 30 seconds later. Finally…

After launching VS2008, R# 4.0 Beta asked me a couple configuration-preference-type questions and then I completely stomped on my code until I could recognize it no more.  (Did I mention the full source tree was already imagecommitted to source control?)  

I played with R# for well over an hour as anonymous delegates became lambda expressions1, object instantiation plus a number of property sets were rolled up into an object initializer2, if statements were inverted, switches became if-else statements, foreachs became to-fors, unused methods were removed, ternary operators were introduced, classes were moved into new files, namespaces were updated and on and on and on and back again.

I know I’ve only brushed the surfaces of what R# can do (3.1 feature list, 4.0 beta feature list,) but knowing R# offers far more than a ridiculous number of refactoring shortcuts, I can’t hardly wait to start using it as I write new code. 

One might consider this recommendation premature, but I encourage you to give ReSharper 4.0 Beta a whirl especially if you are new to Visual Studio 2008 and C# 3.* since R# essentially provides you with a painless primer.  (Can’t get your head around Lambdas?  ReSharper 4.0 will create such an expression for you.) It is a quick download and install and it takes only a few minutes to feel the power of the ALT+ENTER keystroke. 

I hope the Add-in makes coding fun enough to make you giggle.

 

Example Refactor 1

private bool IsAliased()
{
    var computer = computerList.Find(delegate(Computer c)
        { return c.ID == RegistryHelper.MachineID; });
    return (computer.Name != computer.Alias);
}

became

private bool IsAliased()
{
    var computer = computerList.Find(c => c.ID == RegistryHelper.MachineID);
    return (computer.Name != computer.Alias);
}
Example Refactor 2
Notification notification = new Notification();
notification.Message = “Message 1″;
notification.Title= true;

became

Notification notification =
    new Notification { Message = “Message 1″, Title = true };
 

kick it on DotNetKicks.com


Avoid the Word Conservative

11

February

If I were to guess, I receive 2.25 bookstore gift cards and 1.25 books around Christmas each year. Nearly 100% of the tangible books have been non-technical in nature.  This year’s book — Beer School: Bottling Success at the Brooklyn Brewery — was a present from my soon-to-be sister-in-law. 

Cover image for product 0470068671

As I don’t tend to read much these days, it is taking a while to get through this particular gift, but I would already recommend it. It is a nice combination of beer history, entrepreneurial stories/advice and business/people stuff as told by the Brooklyn Brewery founders, Steve Hindy and Tom Potter, a journalist and banker, respectively, in a surprisingly light and down to earth manner.  Note: If you want to learn how to brew your own beer, you will need to turn somewhere else as this book probably isn’t for you. 

While sharing life and business lessons learned while building a successful brewery in NYC, Tom dedicates an entire chapter to the creation of the business plan where he goes as far as to write: “To the extent possible, avoid the word conservative.”  His rationale is clear and to the point:

When a business plan says that it ‘conservatively’ estimates this or sales will ‘conservatively’ reach that, most readers get a suspicious twitch.  When using the word conservative, you’re trying to feed the reader a conclusion and shortcut the private analysis.  It doesn’t work.  Readers will come to their own conclusions, wherever you try to lead them.  The reader is thinking: Don’t tell me that’s a ‘conservative’ estimate; just give me the facts, and I’ll tell you.

It is a very interesting view and, based on my experience with project estimation, I may start taking Tom’s advice to heart.  I mean, how many times have you provided a detailed work breakdown structure with accompanying dev hours just to have a project manager or someone with “authority” change your numbers solely based on their interpretation of the required effort?  This type of thing happens a lot — especially when you include a word like conservative along with your estimate.  In my experience stating an estimate is conservative is a green light for someone else to rework your numbers any way they wish. 

I know I am taking the original tip a bit out of context, but I think it still applies.  Though we tend to have opinions on everything, we might be better off just providing the facts while trusting the recipient will do with our numbers as they deem most fit. I, for one, know most of the folks which receive my estimates are intelligent individuals and they can certainly come to their own conclusions and agree or disagree with whatever I might provide. 

So, when I produce my next estimate, I’m going to present my numbers and the supporting facts and I’m going to keep my opinions to myself.  Well, at least until my estimate is challenged and I am stuck doing twice as much development in half as much time and then all Hell is going to break loose.  :)

kick it on DotNetKicks.com


DotNetKicks "Kick It" Counter Plugin for WLW and WordPress

10

February

This announcement may be yesterday’s news for some, but I just discovered Aaron Lerch’s “Kick It” plugin today and it works like a charm.  If you are using WordPress AND Windows Live Writer is your go-to editor AND your posts tend to be .NET related, give Aaron Lerch’s DotNetKicks “Kick It” Counter Plugin for Windows Live Writer a try.  Again, it works like a charm.  Well, if I am being completely honest, I haven’t tested it yet as I’m not prepared to submit my own post to DNK. So, who’s going to be the first to test the plugin for me?

kick it on DotNetKicks.com


Getting Started with CruiseControl.NET

29

January

I consider myself a neophyte when it comes to continuous integration (CI), but having read up on the topic, “played around” a bit, reviewed a couple of products, and having now incorporated it into our standard development practices, I am starting to hold my own.  If nothing else, the benefits of continuous integration are now obvious and, well, I can’t imagine ever turning back. 

For me, the power of continuous integration extends far beyond build validation.  CI it has become a welcome management tool which allows me to keep my finger on the pulse of numerous developed products as well as individual developer contributions.  Though I am very interested in the overall success/fail state of the current build, equally valuable is the the notifications which email specified team members the code change log which accompanies each build. (i.e. A list modified files and associated comments since the last automated build.)  If you are responsible for overall project success (which typically includes management of deliverable, code quality, task distribution, etc) then continuous integration is for you.

As I mentioned earlier, I reviewed a few products.  Last year, I reviewed FinalBuilder which provided me a nice and easy introduction into this space.  Based almost completely on its popularly and price tag (free), I have since turned to CruiseControl.NET.  I will not claim that was able to quickly get up and running with CruiseControl.NET.  At times, I was down-right questioning if I was smart enough to figure out the product and its configuration.  But, alas, it is now running on a dedicated build machine and my team and I are all the better for it. 

Please let it be known that I am not a wizard when it comes to CruiseControl.NET.  I am, however, good at is documentation of repeatable actions and I tried to capture the steps on getting started with CruiseControl.NET below.  As always, any feedback is greatly appreciated.

By the way, if you are looking for general information on continuous integration or CruiseControl.NET, you are not going to find here.  For more information, you may wish to consult the following:  What is Continuous Integration and What is CruiseControl.NET.

That’s basically it.  Best of luck!

 

1. Find a Build Machine

Though CruiseControl.NET could be installed on a development machine, I recommended that it be installed on a dedicated build server. Your build server should have access your source control repository and an optimal STMP server.  The server should have IIS and the NET Framework installed as well.  More information on the build server to follow…

 

2. Install CruiseControl.NET

Download CruiseControl.NET Server and Dashboard and install using provided default selections. 

http://downloads.sourceforge.net/ccnet/CruiseControl.NET-1.3-setup.exe?modtime=1182463056&big_mirror=0

 

3. Install MSBuild

If you are working with .NET 2.0+ applications, you can build using MSBuild. Otherwise, you may need to learn a bit about NANT.  All of the provided sample configurations below assume you will be using MSBuild. 

The MSBuild DLL is not included in initial CCNET Server installation, but it can be downloaded from the ThoughtWorks site: http://ccnetlive.thoughtworks.com/MSBuildXmlLogger%2DBuilds/. To install, simply copy the ThoughtWorks.CruiseControl.MSBuild.dll into C:\Program Files\CruiseControl.NET\server\ location.

 

4. Install Source Control Client

You will potentially need to install your source control client on the build machine. For the samples provides, we are using Borland StarTeam 2005.  CruiseControl.NET integrates with just about every source control system I could think of, so if you are using something other than StarTeam, you will want to consult the Source Control Block documentation.

 

5. CruiseControl.NET Server Configuration

CruiseControl.NET Server is driven by CCNET configuration file settings. After the fresh install, the configuration is essentially empty and requires manual updates to the ccnet.config file itself. As far as my knowledge, there is no associated configuration editor.  First things first, crack open “C:\Program Files\CruiseControl.NET\server\ccnet.config” in Visual Studios or your favorite XML editor. (There is shortcut under All Programs > CruiseControl.NET > CruiseControl.NET Config.)

If you have a pre-configured ccnet.config file available, simply overwrite the file content. If you are starting from scratch, you may wish reference the online CruiseControl.NET configuration overview and review samples: http://confluence.public.thoughtworks.org/display/CCNET/Configuring+the+Server.  Additional example configuration files were installed on your build box as well: C:\Program Files\CruiseControl.NET\Examples.  They are worth a look.

The bad news: Though you will find examples sprinkled throughout the ThoughtWorks site and the locations noted above, you will most likely need to muck around with your own config file for a while until you get it right.  Additional samples are provide below, but just as I wasn’t able to find the magic configuration combination to get my server running right off the bat, I bet you won’t either. 

The good news: Getting the right configuration was trail-and-error process for me.  I kept the configuration very simple at first and then built upon it.  Hopefully the next steps can help you with your troubleshooting.

 

6. Start CruiseControl.NET Server

The CCNET Server is not started at the time of installation. Thus, you will need to start the service manually: Administrative Tools > Services > CruiseControl.NET Server > Select > Start the service.

If the service fails at startup, it will immediately stop and present the following generic dialogue:

The CruiseControl.NET Server service on Local Computer started and then stopped. Some services stop automatically if they have no work to do, for example, the Performance Logs and Alert service.

If you encounter this error your first stop is to consult the logs: C:\Program Files\CruiseControl.NET\server\ccnet.log. By default, the file contains verbose logging which is helpful (although somewhat difficult to navigate.)  Believe me, the logs are your fried.

Based on the log file feedback, I suggest tweaking the ccnet.config file and then restarting the service – repeating until the service is fully configured.  And, if it is easier for you, you may run the CCNET Server via the command window: CD C:\Program Files\CruiseControl.NET\server > ccnet.exe.  This approach will render errors in the cmd window rather than having to monitor the ccnet.log file.  It was a time saver for me at least.

Once the project is successfully setup, you will see something similar to the following listed in the logs:

· [CCNet Server:DEBUG] The trace level is currently set to debug. This will cause CCNet to log at the most verbose level, which is useful for setting up or debugging the server. Once your server is running smoothly, we recommend changing this setting in C:\Program Files\CruiseControl.NET\server\ccnet.exe.config to a lower level.

· [CCNet Server:INFO] Reading configuration file “C:\Program Files\CruiseControl.NET\server\ccnet.config”

· [CCNet Server:INFO] Registered channel: tcp

· [CCNet Server:INFO] CruiseManager: Listening on url:tcp://localhost:21234/CruiseManager.rem

· [CCNet Server:INFO] Starting CruiseControl.NET Server

· [PROJECTNAME:INFO] Starting integrator for project: PROJECTNAME

At this point, the Server is waiting to initiate the next build. Based on the config file <triggers> setting it could take a while to get the checkout and build to fire. Adjust the following setting to around 10 seconds while still in the testing phase:

<triggers>
  <intervalTrigger name=continuous seconds=10                   buildCondition=IfModificationExists/>
</triggers>

On a similar note, the Server restarts itself automatically each time the ccnet.config file is modified.

 

7. Potential Gotchas

I ran into a couple specific cases while debugging which I suspect could be common issues. 

1. Ensure the MSBuild timeout value allows enough time to the build to complete. This will otherwise return in a failure which wasn’t easy to troubleshoot.

<msbuild>
  <timeout>600</timeout>
</msbuild>

2. For web solutions, update the TargetPath for the Debug and/or Release build of the application to be outside of the source application directory. Otherwise, you will receive the following error:

ASPNETCOMPILER : error ASPRUNTIME: The precompilation target directory cannot be in the same tree as the source application directory.

This can be done by modifying the following in the solution file:

Debug.AspNetCompiler.TargetPath = “c:\ccnet\PrecompiledWeb\SampleWeb\”
Release.AspNetCompiler.TargetPath = “c:\ccnet\PrecompiledWeb\SampleWeb\”

Alternative, one may update the Output location found in the application MSBuild properties.

You may be wondering why an updated solution won’t be updated with the next scheduled build.  As it works out (and makes sense) only changes which are applied to source control are pulled onto the build box. 

 

8. Automating Your Builds

Once the build process is running successfully, modify the <intervalTrigger> setting to a reasonable value and then update the “CruiseControl.NET Server” Service Startup Type to Automatic and then Start the service.  I might suggest also crossing your fingers for the next day or so.

 

9. Monitoring Your Builds

The CCNet Web Dashboard Application is used for reporting a wide range of information. At one end of the scale it reports summary details of all projects being managed by CruiseControl.NET and at the other it can give specific metric output for any specific build.  The Dashboard is setup with your initial installation.  You may access the Dashboard application by navigating a location similar to the following: http://buildbox.com/ccnet/ViewFarmReport.aspx.  For more information on the Web Dashboard: http://confluence.public.thoughtworks.org/display/CCNET/Web+Dashboard

The CCTray an optional utility for use with the CruiseControl.NET Continuous Integration server. It provides feedback upon build progress, and allows control over some of the server’s operations.  As “optional utility” implies, the CCTray isn’t included with the base installation.  You may download the Windows Tray Application from the following location and install using provided default selection: http://downloads.sourceforge.net/ccnet/CruiseControl.NET-CCTray-1.3-Setup.exe?modtime=1182463076&big_mirror=0. There isn’t much to using the CCTray but I do consider it a handy add-on.  Basically, you will find a shortcut to the CCTray on your desktop. Launch the application to begin monitoring the automated build(s) status and schedule.  The information provides via the CCTray is very similar to that which is provided in the Dashboard application.  For more information on CCTray: http://confluence.public.thoughtworks.org/display/CCNET/CCTray.

 

Sample Configuration Files

If you have made it this far, I really, really hope your required configuration is similar to mine.  If so, this is your golden ticket.  I have provided two flavors of configuration files below. You will undoubted need to tweak the files a bit (replace the project locations and names along with credentials will obviously be required), but hopefully these will help get you started.  By the way, the formatting of the XML leaves something to be desires as I have formatted to fit within the given real estate.

 

Windows Service, StarTeam, MSBuild, Emailing and Unit Tests

<cruisecontrol>
  <project name=SampleService queue=Q1 queuePriority=0>
    <workingDirectory>c:\Projects\Services\SampleService
      </workingDirectory>
    <artifactDirectory>c:\ccnet\artifacts\Services\SampleService
      </artifactDirectory>
    <category>Continuous Builds</category>
    <webURL>http://buildbox.com/ccnet/server/local/project/
      SampleService/ViewProjectReport.aspx</webURL>
    <triggers>
      <intervalTrigger name=continuous seconds=600
                       buildCondition=IfModificationExists/>
    </triggers>
    <state type=state directory=c:\ccnet\state/>
    <labeller type=defaultlabeller>
      <prefix>Build-1.0.</prefix>
      <incrementOnFailure>false</incrementOnFailure>
    </labeller>
    <sourcecontrol type=starteam>
      <executable>c:\Program Files\Borland\StarTeam 2005\
        stcmd.exe</executable>
      <project>Project</project>
      <username>user</username>
      <password>password</password>
      <host>10.1.10.100</host>
      <port>11111</port>
      <path>Projects/Services/SampleService</path>
      <autoGetSource>true</autoGetSource>
    </sourcecontrol>
    <tasks>
      <msbuild>
        <executable>C:\WINDOWS\Microsoft.NET\Framework\
          v2.0.50727\MSBuild.exe
        </executable>
        <workingDirectory>C:\Projects\Services\SampleService
          </workingDirectory>
        <projectFile>SampleService.sln</projectFile>
        <buildArgs>/noconsolelogger /p:Configuration=Debug /v:m
          </buildArgs>
        <targets>Clean;Build</targets>
        <timeout>600</timeout>
        <logger>ThoughtWorks.CruiseControl.MsBuild.XMLLogger,
          C:\Program Files\CruiseControl.NET\server\
          ThoughtWorks.CruiseControl.MsBuild.dll</logger>
      </msbuild>
      <msbuild>
        <executable>C:\WINDOWS\Microsoft.NET\Framework\
          v2.0.50727\MSBuild.exe</executable>
        <workingDirectory>C:\Projects\Services\SampleService
          </workingDirectory>
        <projectFile>UnitTestBuild.proj</projectFile>
        <buildArgs>/noconsolelogger /p:Configuration=Debug /v:diag
          </buildArgs>
        <targets>Tests</targets>
        <timeout>1500</timeout>
        <logger>ThoughtWorks.CruiseControl.MsBuild.XMLLogger,
          C:\Program Files\CruiseControl.NET\server\
          ThoughtWorks.CruiseControl.MsBuild.dll</logger>
      </msbuild>
    </tasks>
    <publishers>
      <merge>
        <files>
          <file>c:\ccnet\artifacts\Services\SampleService\
            mbUnit-testResults.xml</file>
          <file>c:\ccnet\artifacts\Services\SampleService\
            msbuild-results.xml</file>
        </files>
      </merge>
      <xmllogger/>
      <email from=no-reply@buildbox.com
              mailhost=localhost includeDetails=TRUE>
        <users>
          <user name=User 1 group=BuildMaster
                  address=user.one@buildbox.com/>
          <user name=user 2 group=TechLead
                  address=user.two@buildbox.com/>
        </users>
        <groups>
          <group name=BuildMaster notification=always/>
          <group name=TechLead notification=change/>
        </groups>
      </email>
    </publishers>
  </project>
</cruisecontrol>

Web Application, StarTeam, MSBuild, Emailing, and Build Dependencies

<cruisecontrol>
  <project name=SampleWeb queue=Q2
           queuePriority=1>
    <workingDirectory>c:\Projects\Web\SampleWeb
      </workingDirectory>
    <artifactDirectory>c:\ccnet\artifacts\Web\SampleWeb
      </artifactDirectory>
    <category>Continuous Builds</category>
    <webURL>http://buildbox.com/ccnet/server/local/project/
      SampleWeb/ViewProjectReport.aspx</webURL>
    <modificationDelaySeconds>15</modificationDelaySeconds>
    <triggers>
      <intervalTrigger name=continuous seconds=3600
                       buildCondition=IfModificationExists/>
      <projectTrigger project=SampleData>
        <!– Force build when data component is successfully built. –>
        <triggerStatus>Success</triggerStatus>
        <innerTrigger type=intervalTrigger seconds=30
                      buildCondition=ForceBuild/>
      </projectTrigger>
    </triggers>
    <state type=state directory=c:\ccnet\state />
    <labeller type=defaultlabeller>
      <prefix>SampleWeb-Build-</prefix>
      <incrementOnFailure>true</incrementOnFailure>
    </labeller>
    <sourcecontrol type=starteam>
      <executable>C:\Program Files\Borland\
        StarTeam Cross-Platform Client 2006 R2\stcmd.exe</executable>
      <project>Project</project>
      <username>user</username>
      <password>password</password>
      <host>10.1.10.100</host>
      <port>11111</port>
      <path>Projects/Web/SampleWeb</path>
      <autoGetSource>true</autoGetSource>
    </sourcecontrol>
    <tasks>
      <msbuild>
        <executable>C:\WINDOWS\Microsoft.NET\Framework\
          v2.0.50727\MSBuild.exe</executable>
        <workingDirectory>C:\Projects\Web\SampleWeb
          </workingDirectory>
        <projectFile>SampleWeb.sln</projectFile>
        <timeout>900</timeout>
        <buildArgs