April 2011 - Posts

Generic Repository (something like Repository<T>) is a good concept with intention of keeping code DRY, though problematic. Here are a few drawbacks of a generic repository:

  1. It is not always logical to call behaviours Save, Delete, etc on all repositories
  2. Support (logging as an example) requires to know what specific repository was invoked, and not just Repository<T>

Just recently I ran into a log with an exception, where operation on …Repositories.Repository`1.Save(T obj...) failed and there was no way to figure out what repository out of 4 different one actually failed save operation.

I really loved the last exhibit at the Royal Tyrrell Museum (door with the words):

Species come and species go. The only constant in life on earth is change.

Agile Fundamentals is an online course ThoughtWorks is provided free of charge. The subjects discussed are

  • Origins
  • Core Practices
  • Technical Practices
  • Quality
  • Planning/Communicating

This is a good primer for Agile. If you want to have a quick introduction, this course will be helpful.

I have started this book long time ago, but never got to end of it. Finally, I had a imagechance to do so. What a great book. The cover says “The Expert’s Voice in .NET”, and I found Seven Sanderson a real expert in ASP.NET MVC.

In the past, I did a lot of WebForms work. These days I spend a lot working on ASP.NET MVC and like it way more. Primarily for the reasons of testability and being closer to the real web (stateless and mark-up).

If you are looking for a good ASP.NET MVC book or just a reference/refresher, this one is worth reading.

This a neat shortcut assignment I probably will end up using a lot Smile

TDD causes different people react to it in a completely different way. Some just jump on it like on a glass of a cold sparkling drink in the heat of a summer day. Some run away from it like it’s a wild dog ready to take a bite. Some feel that there might be a value for them in it, but don’t really want to move away from the comfort zone. And the last group of people always have an interesting way making an attempt to justify why having no TDD is good.

A classical example would be the current project I work on – integrating .NET sub-system with C++ components/subsystem. I stick to TDD because I know the value is enormous, but not instantaneous, it comes with time. During integration with C++ subsystem, there was some weird behaviour with no clarity where would it break (managed or unmanaged code). Sure thing my steps where to validate that all tests cases present. And sure they did. Within seconds I could not only confirm that I am dealing with all various edge-cases, but also run the “executable specifications” to verify code adheres to expected behaviour / design. And guess what, the bug was identified on… the side where developer was so convinced that “previous experience would compensate for lack of tests” that there’s no point of even bothering with TDD. Ironic.

But what’s the moral of the story?

If you on your path to start TDD, or trying to show others the benefits – don’t cave in, be patient and keep doing what you do. It is unavoidable, and eventually the simple truth will come out. TDD works just like medicine – once it’s in the blood stream, it will sure kick in.

I ran into this problem just recently on a project that has more than a single repository for a project. Using Jenkins (Hudson) was awesome for the past 2+ years and I was surprised that it couldn’t handle revision environment variable assignment when more than a single module had a place in a build job. According to some threads, this is done by design. One workaround in particular that I liked was to look into the poll log file and get information out of it.

This is a quick implementation of a get-revision function for nant to grab revision based on the project name (stringToSearch argument) and its looking at the polling log file per project.

.
   1: <script language="C#" prefix="utils">
   1:  
   2:         <imports>
   3:             <import namespace="System.Globalization"/>
   4:             <import namespace="System.IO"/>
   5:       <import namespace="System.Text.RegularExpressions"/>
   6:     </imports>
   7:         <code>
   8:             <![CDATA[
   9:               [Function("get-revision")]
  10:               public static int GetRevision(string filePath, string stringToSearch) 
  11:                             {
  12:                 if (!System.IO.File.Exists(filePath))
  13:                   return 0;
  14:                                 System.IO.FileInfo file = new System.IO.FileInfo(filePath);
  15:                 using (System.IO.StreamReader stream = file.OpenText())
  16:                 {
  17:                   System.Text.RegularExpressions.Match match = System.Text.RegularExpressions.Regex.Match(stream.ReadToEnd(), stringToSearch + @".*\srevision\s(?<revision>.*?)\r #string_to_search <ANYTHING>revision(group_revision)\r",
  18:                     System.Text.RegularExpressions.RegexOptions.Multiline |
  19:                     System.Text.RegularExpressions.RegexOptions.IgnoreCase | 
  20:                     System.Text.RegularExpressions.RegexOptions.IgnorePatternWhitespace);
  21:                   return match.Success ? int.Parse(match.Groups["revision"].Value, System.Globalization.NumberStyles.Any) : 0;
  22:                 }
  23:               }
  24:             ]]>
  25:         </code>
  26:     
</script>

And this is how the typical usage would look like:

   1: <property name="svn.revision" value="0" readonly="false"/>
   2:  <if test="${environment::variable-exists('SVN_REVISION')}">
   3:    <property name="svn.revision" value="${environment::get-variable('SVN_REVISION')}" />
   4:  </if>
   5:  <if test="${not environment::variable-exists('SVN_REVISION')}">
   6:    <property name="svn.revision" value="${utils::get-revision('.\..\scm-polling.log', project::get-name())}" />
   7:  </if>

As an afterthought, I could actually set SVN_REVISION to the value from the log, and then work with SVN_REVISION as usual.

More Posts