Sunday, July 17, 2005

Tips to avoid breaking the build

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/tips_to_avoid_breaking_the_build.htm]

As automated builds become more popular, one of the main principles is to avoid breaking that build. The basic idea is that your team has an official server that regularly gets all the source code from source control and recompiles the entire project. If you check in source code that causes the build to not compile on this server, then you broke the build. We assume that the relevant environment (programs, external DLLs, version of .Net) on your machine is the same as the build server, as these change infrequently. Of course this dedicated server can do more than just compile the code, such as run automated unit tests. Check out NAnt for links on this.

Nobody wants to be the person who breaks the build. Here are some tips that I've learned (the hard way). The main concept is that before you check in changes, you want to compile the code on your machine, and if your code matches the code on the server, then it should compile on the server too. Build problems often result with your dev machine being out of sync with the build server.

  1. Work in small increments because there is less that can go wrong. Someone once said "Integration is a pay me now or pay me later" (I think it was Fowler). It's easier to integrate 5 small things than 1 big thing. Therefore if you're given an extensive 2-week task, see if you can break it into daily increments, where each check-in is still functional. XP talks about this more.
    1. For new classes that are in progress, you can check in just the class to "shelf it". As long as you don't check in the project, the build server won't try to compile it. For example, say you're spending 1 week on a new WebForm. You could check in your progress at the end of each day without fear of breaking the build because that file isn't included in the build.
  2. Use a source control that allows multiple people to check out the same file. This is why I no longer want to use Microsoft's VSS for enterprise apps, which has such a file-lock model. CVS or Subverion do not. Certain common files, like the *.proj file are constantly being updated as new pages are added to the project, and it's just a constant thorn for a 10 person team to let only 1 person check this out at once.
    1. NOTE: If you do need to use a file-lock source control system, them minimize the time you have such global files checked out. For example, you may add all the new files you need, and then check back in the *.proj file before implementing those classes. This will (1) Not break the build because you haven't implemented anything, (2) Give you the files you need to finish your task, and (3) not have that global file checked out.
  3. Before checking into the repository, update your local source to the latest from source control. This helps prevent some other dependency that changed from breaking the build. Even if your code compiled before, this helps ensure that someone else didn't change something such that the official build gets broken when you check in.
  4. For complex changes, check in everything at once. Partial check-ins are a common cause of broken builds. For example, say you add a class to the project, but only check in the project file. The code on the build server now has the updated project file, but not the class it was expecting, and the build will break.

Another technique, one I've only heard of but never implemented myself, is to have a queue. I think some groups at Microsoft do this. The idea is that instead of checking your code directly into the official build, it is checked into a queue instead. Then a process on the build server takes each fileset, one at a time, and integrates it into a temp build. If and only if that passes, then it adds the fileset to the official build and removes it from the queue.

[Update]: If the build is broken, try to avoid checking in source code. This will (1) make it easier to fix the build because it's not changing, (2) limit your association with the broken build.

Wednesday, July 13, 2005

Visual Studio Design Mode Changing your Html

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/visual_studio_design_mode_changing_your_html.htm]

Occasionally Visual Studio (2003) changes the Html when you go to design mode. While it reformats it, it may also add certain closing tags. This can be counter-productive if you're doing certain techniques where you want the Html to be the way you initially made it. I've heard rumors that 2005 guarantees that your Html won't get altered.

I see this Html changing in two categories:

  1. Ways you can solve it by adding extra html, such as multiple nested tables
  2. Ways that Visual Studio is just wrong

The problem with the first is that any extra html you add must be transported over the wire and rendered on the client, so it slows performance. The only helpful technique I know to avoid needing that extra overhead is to make Visual Studio open in Html view by default.  Goto: Tools > Options > Html Designer > General, and set the options to open in Html instead of Design view. Ideally your UI is refactored enough (with user controls, base pages, custom controls, possibly #includes, etc...) that the Html can be managed in Html view. I can then save my page, "peek" in design view to check the overall layout, disregarding any potential changes from Visual Studio.

In the second category, one (seemingly) blatant bug I came across in Visual Studio was when I had a custom control with custom attributes, and the attribute didn't have a value (kind of like "nowrap" - it only needs the attribute, not any associated value). Something like:

...

kept getting maligned to something like below when I went to design view. The attribute values got disjointed from the attributes:

...

However if I put the value-less attribute at the end, then I could toggle back and forth between Html and Design view:

...

I'm not sure what causes this - it could be something with the custom control, value-less attribute, affect from other attributes, or something else, but it solved that particular problem.

Sunday, July 10, 2005

System.Web.HttpException: External component has thrown an exception

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/systemwebhttpexception_external_component_has_thrown_an_exce.htm]

As far as debugging difficulty goes, anything that you can reproduce and step through with the debugger is likely simple. Sometimes you'll get an error that occurs before the codebehind is even hit, and you therefore can't debug it like "normal". One such error is: "System.Web.HttpException: External component has thrown an exception."

Web pages integrate both the aspx and codebehind pages. What may be happening is that some control in the html of the aspx page has an onserver attribute that references a non-existent server event. For example, you may have copied from a similar page that had a LinkButton with attribute onserverclick="AddLink_Click". The WebForm expects an "AddLink_Click" method in the codebehind. The original page may have had this method, but perhaps the target page does not. Therefore when you try to load the page, it can't "merge" the aspx and codebehind correctly and therefore crashes before even going to a breakpoint in the CodeBehind's Page_Load.

The solution (in this case) is to ensure that any attributes set in the aspx page are consistent with the codebehind.

Wednesday, July 6, 2005

Why I love XmlSpy with XSD Schema Editor.

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/why_i_love_xmlspy_with_xsd_schema_editor.htm]

Before coming to Ameripay's  Software Engineering department, I used to do consulting. Because with consulting, everything (such as what software you have licenses for) is project-driven, my software was often on the cheap. Clients and managers were very hesitant to pay for licenses for "frivolous" software, especially with the previous IT recession. Therefore certain things, like editing Xml Schemas, I often did the harder, manual way. For simple schemas this works, but it just becomes draining (You can learn the basics of Xml Schema at the online W3Schools).

Now I have XmlSpy installed, and it's great if even just for the schema editor. I've heard many good things about this popular tool, but never got the chance to check it out myself. The help section even has a step-by-step tutorial. It looks like Altova even offers a free XmlSPy Home Edition to get you started.

Yet another tool I wish I had had before.

Monday, July 4, 2005

Batch code generation with CodeSmith Console

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/batch_code_generation_with_codesmith_console.htm]

I'm always keeping my eyes open for practical tools that save time and mental sanity. One of the most mentally-draining tasks is repetitious modifying of simple code. For example, many simple CRUD (Create-Read-Update-Delete) stored procedures, and their accompanying DAL and Business Objects are redundant. Ideally we could just auto-generate this given the inputs. Auto code generation is a great time saver, which frees us from boring tasks to focus on interesting ones.

CodeSmith is a great code generator. It has both a free and purchase version, it has a large support community, is time tested (been out for several years now), and has great functionality. It's based around writing templates with ASP syntax, which is much more friendly then using XSL or writing your own C# app to assemble the target code. Therefore part of a CodeSmith template may look like:

private void <%= SampleStringProperty %>()
{
    // <%= GetSomething() %>
    // Do something
}

There are plenty of tutorials about auto-generating your data access layer. But one thing I really like about CodeSmith is its batch processing. These are features I'd like in batch processing:

  • Ability to call the tool from a command line, passing in an Xml config file
  • Extend step 1 to generate many objects from a single Xml file, as opposed to calling the exe each time.
  • Ability to merge your changes into an existing, non-generated document.
  • Ability to auto-generate a document, but leave certain sections open to customization

The first two help with batch processing, such that you could generate an entire layer at once. The last two help with versioning and customization. You need to both made custom modifications to templates, and then not have those overwritten upon re-running the tool.

CodeSmith offers both several help guides, and samples, to assist with these. Check:

  • CodeSmith Console Tutorial in the CodeSmith Studio's Help section
  • Samples at: "CodeSmith\v3.0\SampleProjects\ConsoleSamples\GenerateCode.bat"

If all you have is a hammer, everything looks like a nail. With a good code-generation tool, you start viewing all those redundant tasks very differently.

Wednesday, June 29, 2005

AJAX - Asynchronous JavaScript and XML

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/ajax__asynchronous_javascript_and_xml.htm]

Until recently, I assumed that web applications were based on a strict client-server / request-response model. This has several limitations, such as a thin client (your web browser) not being able to do any *real* business logic. For example, say you need to validate against a back-end data source such as ensuring a username-password combo is valid or checking if a city exist within a state. As this is really outside the scope of JavaScript, it would require a hit to the backend, and then re-posting the page.

But what if you could just do a "postback" for the desired field only, leaving the rest of the page unchanged? And what if you could have the server automatically update the client without the client initiating the event?

A technology, Asynchronous JavaScript and XML (AJAX) looks like it can do just that. Quoting from Adaptive Path's Jesse James Garrett:

[Quote]

Ajax isn't a technology. It's really several technologies, each flourishing in its own right, coming together in powerful new ways. Ajax incorporates:

  • standards-based presentation using XHTML and CSS;
  • dynamic display and interaction using the Document Object Model;
  • data interchange and manipulation using XML and XSLT;
  • asynchronous data retrieval using XMLHttpRequest;
  • and JavaScript binding everything together.
     

[End Quote]

Check out these sites for more detail:

This looks like it has a ton of potential, and I'm looking forward to checking it out and doing a future blog post on a sample.

Wednesday, June 22, 2005

Enterprise Library Tips for Strong Names and Versions

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/enterprise_library_tips_for_strong_names_and_versions.htm]

Previously I offered some tips for configuring Enterprise Library. Today I'll discuss another problematic area - adding strong names.

First, this builds on concepts about Strong Names and PublicKeyTokens.  You may need to add a strong name to the EntLib blocks if you include it in a project that already uses strong names (because this requires that all assemblies being referenced also have strong names).

To add a strong name, you'll need to create a key and reference it in the AssemblyInfo.cs file.

Strong Names and Versioning Tips

0 - You will need to add the key to the source code. Microsoft gives us the source code partially so that we can do things like this.

1 - Put properties (like strong-naming) in the GlobalAssemblyInfo.cs. This requires you to remove (or comment out) the key from the other 38 AssemblyInfo files, however it lets you change it in one place.

2 - Note that there are two places that DLLs are stored.

  • C:\Program Files\Microsoft Enterprise Library\bin
  • C:\Program Files\Microsoft Enterprise Library\src\\bin

Opening the EntLib solution and compiling creates copies in the \src dir. You still need to copy these to the \bin
Make sure to run the "Copy Assemblies to Bin Directory" script included in the EntLib start menu. If you're not putting DLLs in the GAC,  EntLib's config tool pulls DLLs from the \bin dir. So you'll notice strong-name nightmares if you don't do this. It will set the assembly name (like PublicKeyToken) from those DLLs, not merely the ones used in your project. For example, check the version of the DLLs loaded by the config tool, and make sure that they include the strong name.