CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Jeffrey Palermo (.com)

Blog moved to www.jeffreypalermo.com

March 2006 - Posts

  • Consider voting for my Birds of a Feather session at Tech Ed - level 100

    I have submitted two BoF sessions for consideration.  These two subjects are ones I deal with ona  day-to-day basis.  If you are going to Tech Ed and are interested in these topics, go to https://www.msteched.com/cfp/bofvoting.aspx and vote.

    Voting closes on Friday!

    Executable requirements with FIT and FitNesse
    What if your requirements documents could be fed into a tool and executed to validate the software? That's exactly what FIT is. The customer can define requirements and run them. Not only can software be validated at any time, but requirements are guaranteed to remain current documentation of the system. Come discuss this emerging concept and tools to support it.
    Intended Audience: IT Pro; Developer
    Submitted By: Jeffrey Palermo, DataCert, Inc

    Agile Development with .Net Agile development is gaining wide adoption and for good reason. Come discuss the range of practices available to speed development with .Net. We'll discuss the many practices in the Agile umbrella that can be used by themselves and combined together. This discussion will also talk about tools available to help with development.
    Intended Audience: Developer
    Submitted By: Jeffrey Palermo, DataCert, Inc
  • Juice is an open source podcast downloader - level 100

    Blake Caraway made me aware of this cool program.  Juice is a podcast downloader and manager.  Install this small program and subscribe to your podcast feeds.  Juice will automatically take care of updating these feeds and sucking down the new podcasts.  Once set up, all you have to do is copy the files to your MP3 player every once in a while. 

    Until I found this, I'd been manually saving off each podcast file.  This program fills a very specific niche, and I thank the authors!

  • Rocky gets it all wrong about Test-Driven Development (TDD) - level 200

    I'm listening to the latest .Net Rocks show with Rocky Lhotka, and I'm saddened that he gets it so wrong about TDD.  DNR's last episode ROCKED with Jean Paul Boodhoo, who talked about TDD and other Agile concepts.  Jean Paul is a practitioner of TDD, as am I, and he explained the process and its benefits very well.  Congrats, Jean Paul on a job well done.

    Rocky, on the other hand, gets it all wrong.  I respect Rocky and his contributions to the developer community, but he's wrong on this issue.  Let me recap:

    At the beginning of the dnr show, he comments on TDD.  He makes some invalid points.  His points are bulleted, and my responses are in green:
    • It comes from the premise that you don't have intellisense in the IDE.
      • I'm really not sure how he came up with this since most other good IDEs have intellisense. 
    • In the Microsoft space, you lose so much by going down the road to TDD.
      • This is a very vague statement, but I've gained so much by doing TDD.  My rate of development has sped up because my debugging time has gone almost down to zero!
    • Rocky misunderstands the process because he states that it involves writing a bunch of tests first before coding.
      • TDD involves writing a single test first and writing code to fulfill it.
    • He states that on large systems, you can't do it one test method at a time.
      • Can't?  Any large system is made up of smaller parts, down to actual classes and methods as the building blocks.  TDD helps define the classes and methods.  TDD forces you to start small, but helps build a solid foundation.
    • He says that developers don't think the way of "test-first".
      • This is actually a true statement but in no way is a weakness of TDD.  Test-first is a learned method just like programming as a whole.  Learning to think first is very similar to understanding the purpose of the code first.  If you can understand the purpose of the code before writing the code, you end up with less code churn and a clean class design.
    • Rocky relates that he has always made small test projects or console apps to be test harnesses to test code.
      • I used to do that also, until I graduated to NUnit.
      • These test harnesses are valuable, but as you accumulate them, they are hard to manage, and since they are valuable, you don't want to throw them away.  NUnit allows these test harnesses to be managed effectively.  Each test method is a test harness.
    Another false point made in conversation is that once these test fixtures are created, developers will be hesitant to refactor code because it would cause them to have to refactor all the tests that use the code.  Let me say from experience that unit test coverage makes me want to refactore MORE!  I am so comfortable refactoring because I have unit test coverage that assures me that I haven't broken anything.  In fact, when I am in parts of the code that is older and doesn't have good test coverage, I am scared of refactoring because I have no way of being sure that I didn't break anything.  Note, that I also use Resharper, and I would not want to code at all without it or the DevExpress tools.

    I love .Net Rocks, and I've listened to it from the very first show (and I've been a guest), and I'm glad all viewpoints are represented, but the above bullet points are incorrect, and I hope some of you will comment on them as well.

  • Keep Virtual PC from hogging your computer while installing Windows Vista ctp - level 200

    I'm installing the CTP of Vista on a Virtual PC to check it out, but the install is going to take a while, and I don't want VirtualPC to hog my CPU while I work (no dual core proc for me yet).  I have plenty of RAM, so that's not an issue, so my CPU is the bottleneck in computer speed.  I found a simple solution that allows me to continue to work while a Virtual PC is cranking away.

    Set the thread priority of Virtual PC to "low".  Windows will now allow anything else to run more often than Virtual PC (cpu timeslicing).  If you've never adjusted thread priorities before, you can do this with Task Manager.  Notice that my Commit charge is high, but I have 2GB of RAM, so I'm not worried.  At the top, notice that I have a NAnt build running.  I want NAnt to go fast, so it's normal priority.  The only process I've changed is Virtual PC.

    Note:  I almost never change thread priorities, and I don't recommend doing so, but in this case, it serves a specific purpose.

    Windows Vista is slowly installing in the background while I'm able to continue to work without being affected.  Virtual PC is effectively only using idle CPU time.
  • Blake Caraway defines "Team Smells" - level 100

    We all know about code smells, but Blake Caraway is defining some team smells.  Great post!
  • Web service versioning for dummies - level 200

    This post is aimed at providing a good way to version web services.  Note that there are many ways to do this, and this is just one way.

    When versioning a service, it's important to be able to run multiple versions side by side.  When you upgrade the web service for one client, you can't immediately take away the current version from existing clients.  Existing clients will move to the new version if/when they can/want to.

    The identifier for the web service is the Url, so the version number must be embedded in the url.

    Here is one way to do it:
    https://theServer/v1_0/theService.asmx
    When you want to modify the web service, do so, but deploy it side-by-side with the current version:
    https://theServer/v1_5/theService.asmx

    With this versioning strategy, you will be able to publish upgraded web services while maintaining service to existing customers.  Down the road, when you have confirmed that all customers of the v1.0 service have moved to the v1.5 service, you can discontinue the v1.0 version.

    I've learned that if there are urls with dots (.) in the path, then the IIS lockdown tool won't work with them.  For that reason, it's probably good to use (_) instead of (.) for the version delimiter.  I also agree with the first commenter that major and minor versions are enough.

    There are plenty of folks talking about web service versioning:
    http://www-128.ibm.com/developerworks/webservices/library/ws-version/
    http://www.webservicesarchitect.com/content/articles/irani04.asp
  • Integrate FitNesse tests with CruiseControl.Net - level 400

    On my team, we have FitNesse tests surrounding our system.  We've integrated them into our cruise build as well.  We developed custom Xsl sheets so that the cruise build report includes fitnesse information.  We even have our regression FitNesse suite fail the build if any FIT tests fail.  When this happens, the cruise build report shows us the actual FitNesse test that failed with the actual fixture tables.  It's a great way to report this status.  If you are interested in this technique, my colleague, Steve Donie has posted the Xsl stylesheet on his blog.
  • Using enum strings with NHibernate persistence - level 400

    One of the things that is not very obvious when using NHibernate is how to using Enumerations.  If you merely map an enum with the hbm.xml, NHibernate will persist that class member as an int, which is the underlying type of an Enum value type.  Even if you have your database table configured with a string field, you'll get an integer in your string field.

    To have NHibernate use the string representation of the enum for storing in the database, you need to use a special type class.  Below is a simple example of using the EnumStringType that NHibernate provides.  Consider the following enum that I want to use in my class (this is a very simplified example):

        public enum DeliveryStatus
        {
            Pending,
            Ready,
            Sent
        }


    When mapping this in my class, NHibernate would persist 0, 1, and 2 in my database.  What I actually want are the strings to be stored in my table (no comments about normalization, please).  Here is a wierd thing you have to do to achieve this goal.  Here is my mapping:
    <?xml version="1.0" encoding="utf-8" ?>
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
        <class name="Palermo.Shipping.Shipment, Palermo.Shipping" table="Shipment">
            <id name="TrackingId" column="TrackingId" type="String" length="30" >
                <generator class="assigned"/>
            </id>
           
            <property name="DeliveryState" column="DeliveryState"
                type="Palermo.Shipping.DeliveryStatusType, Palermo.Shipping"/>
           
        </class>

    </hibernate-mapping>


    Notice that I have a new type referenced for DeliveryState:  DeliveryStatusType.  This is what's new.  This type helps NHibernate map an enum string instead of the int.  For this, I must define this type in my code:

        public class DeliveryStatusType : EnumStringType
        {
            public DeliveryStatusType() : base(typeof (DeliveryStatus), 30)
            {
            }
        }


    Note that this is very simple, and the 30 specifies the max length of the enum string.  I'd recommend setting this number the same as the length of your string field in your database.

    With these small steps, NHibernate will now map Pending, Ready, and Sent to the database field.  Normal programmatic interaction is the same.  NHibernate will take care of all the data access.  Without the above solution, one might be tempted to use string constants, but I'd highly recommend using enums when the possible values are known. 
  • INETA speaker Miguel Castro at ADNUG tonight - level 000

    Miguel Castro will be talking about custom web controls tonight at the Austin .Net User Group.  If you've heard his .Net Rocks show or watched his DNR TV episode1 and episode2, you know that it'll be a great talk for those wanted to create their own custom controls.

    Miguel came into town (Austin, TX) Saturday night, and I spent Sunday showing him around the area.  It's beautiful hill country, and he was amazed that while driving past houses, complete strangers would smile and wave.  The greater Austin area is so much more than just the city of Austin.  I would say that the city is the smallest part.  The surrounding area is really the draw.  I live two towns away in Leander, TX, and it still only takes me 30 minutes to get in to Austin to work. 

    One of the things that amazed Miguel most is that here in Texas, our Wal-marts have gun departments. :-)
  • EVERY application has a natural domain model - level 200

    I'm in the camp that loves OO.  I want smart objects for everything.  I don't like data-centric programming.  I don't like thowing raw data around in DataSets.  I create custom objects for everything in my applications.  I was reflecting on a very simple application, and I realized that every application has a natural domain model.  I've had conversations where a developer has said, "Our application is different.  It's not an enterprise application.  Domain-driven design doesn't apply."  I've come up with a really simple example to illustrate my point.

    Suppose you have an application that only maintains social security numbers.  That's it. It doesn't store person information, just social security numbers.  In fact, your entire database is one table with one char(9) field.  One might just go ahead and keep the social security numbers in a string.  Would that work?  Yes, but consider the natural domain object for this:

        public class SocialSecurityNumber
        {
            private string _rawNumber;

            public SocialSecurityNumber(string number)
            {
                _rawNumber = number;
            }

            public string GetWithoutDashes()
            {
                return; //the ssn without dashes.
            }

            public override string ToString()
            {
                //format ssn nicely and output.
                return; //the nice output.
            }

            public override bool Equals(object obj)
            {
                return true; //or false if they don't match.
                //Use some intelligence to compare for sameness.
            }
        }


    You could store the information in a string, but then that is a magic string floating around your application, and every class _just_ has to know that it must be a social security number.  There is no strong typing to enforce that there are exactly 9 numerals in the string.  What about dashes?  with this SocialSecurityNumber class, you have your domain model, and now you can enforce all the rules about the number easily.  Maybe you want to always store it in the database without dashes but want to display it on the UI with dashes.  Instead of string manipulation elsewhere, encapsulate that logic directly inside the domain object.  If you use this object throughout your system, it's clear that constraints will always be enforced, and you never have double check that a social security number is really there - the compiler picks up that burden for you as well as runtime strong type checking.

    Consider your current applications.  Do you have a prominent string, bool, or int?  Would it be helpful if that piece of information could carry around describing and validating information?  Consider creating a domain object to house that single piece of information and enforce rules about it.  I think it'll make the application a lot simpler.

  • How VirtualPathUtility combines paths in .Net 2.0 - level 100

    This is a warning that the VirtualPathUtility class in .Net 2.0 takes some time to understand the rules under which it operates.  It wasn't obvious to me, and I had to do some investigation to learn it's behavior.  I expected the following test to pass.  It didn't.

            [Test]
            public void ShouldCombineTwoWebsitePaths()
            {
                string parentPath = "/websiteRoot";
                string subDirectory = "newPage";
                string expected = "/websiteRoot/newPage";

                string actual = VirtualPathUtility.Combine(parentPath, subDirectory);
                Assert.AreEqual(expected, actual);
            }


    I expected it to actually "Combine" the base path and the path that was relative to the base path.  After all, if these combine, the product will be the sum of both, right?  Not really.  Here's my test output:

        String lengths differ.  Expected length=20, but was length=8.
        Strings differ at index 1.
       
        expected:<"/websiteRoot/newPage">
         but was:<"/newPage">
        ------------^

    Thanks to the first comment below, I realized that this method tries to act like a web browser in resolving relative paths.  If I add a "/" to the end of "/websiteRoot", the test would have passed.  As it stands, it assumes that "websiteRoot" is a page and not a directory.

  • Hiding errors is evil - level 200

    Hiding errors:
    • Swallowing informative excpetions
    • Returning a magic value instead of the error
    • Ignoring errors
    I'm sure many can relate this this experience:  I'm using an application or a programming API.  The code runs and returns.  I move on.  I find out later that the code failed, and the work was never done.

    This scenario can kill an application's reliability and reputation.  When this happens, you don't find out about errors until some time later.  Because of this, you really can't say that the application is working correctly at any point in time unless you explicitly investigate a log somewhere where errors are stored.

    Hiding errors makes life harder.  Finding out about errors when they happen makes for more reliable systems.  I'll give one quick example from the .Net Framework v2.0.  This example uses C#.
                

    string loweredUrl "/mypage.aspx";

    string loweredApplicationPath = "/myApplication";

     

    string appRelativeUrl = VirtualPathUtility.ToAppRelative(loweredUrl, loweredApplicationPath);

    Console.WriteLine(appRelativeUrl.Length);


    This seems simple enough.  We're using the VirtualPathUtility class to convert a url to it's application-relative form.  In this case, I'm passing an invalid argument in.  The rule this method uses is that if the url is not a part of the given application path, it's invalid.  What does VirtualPathUtility do in this case?  It returns NULL!  I passed in an invalid argument, and it returns null.  The more appropriate response would be throwing an ArgumentException.  Because of this error hiding, I have to know the internal rules of this method and code around them.  I can't afford for this code to continue while appRelativeUrl is null.  The next line would throw a NullReferenceException.

    Because of the error hiding, my code ends up like this:

    string loweredUrl "/mypage.aspx";

    string loweredApplicationPath = "/myApplication";

     

    if (!loweredUrl.Contains(loweredApplicationPath))

    {

        throw new ApplicationException(string.Format("url {0} is not in application path {1}", loweredUrl, loweredApplicationPath));

    }

     

    string appRelativeUrl = VirtualPathUtility.ToAppRelative(loweredUrl, loweredApplicationPath);

    Console.WriteLine(appRelativeUrl.Length);


    I have to do an explicit check and compensate for the undesirable behavior of the API.

    If an error condition happens, I want to know about it.  The term "fail fast" is very popular.  It means that if the application encounters a condition where it can't continue, stop now and output the exception information.  Don't have the application limp along until it crashes in flames.  If you break your arm, you stop what you are doing and get a cast put on.  Yes, you _could_ go to work if it's not your mousing arm, but you cause less damage if you stop right away and address the problem.
  • SOA has not lived up to it's hype - level 200

    A quick google search will reveal a raging debate on the merits of SOA.  It has cooled down a bit from 2005 where every time I turned around, there was another session at Tech Ed on SOA.  The talk about SOA has just started if its landscape is going to be anything like the adoption landscape for OOP.  SOA has not lived up to it's hype yet, but to be fair, we have to give it another two decades. 

    We don't think about it much, but object-oriented programming began in the 1960's with the Simula language.  Smalltalk helped the movement, but C++ brought object-oriented development into the mainstream in the late '80s when the ANSI group was formed.  From 1962 to 1989, OO was a lot of talk and theory with handfuls of folks implementing real systems using the concepts.  When C++ hit, many more programmers came on board.  Java furthered the adoption of object-oriented concepts, and .Net seems to have pulled the remaining part of the programming market into OO.  When I think about how long it has taken for the average programmer to ackowledge OOP, I wonder if it will take that long for other paradigm shifts.

    It remains to be seen if SOA really has the merits granted it by all the marketing hype or if it is just a new name for integration.  We won't really know for at least another decade, I imagine.  Folks have been integrating systems when necessary for years, so it remains to be seen if this new (everything is exposed as a service) strategy works.

    I like the way Jeremy Miller puts it:  "The 'if you build it, they will come' approach doesn't work."  I agree.  As with any part in programming, building something with the wish that someone will use it someday doesn't work.  If you are adding a service endpoint to a system out of necessity because someone else need to integrate NOW, then the business value is there, and it's the same kind of integration that has been going on for years.  Some large companies need to integration now, and we see case studies galor: google search.

    What we won't find out until many moons from now is if these SOAs worked.  Every project is declared a success immediately after completion, so we can't count on reported results right now.  The true test is if these integrated enterprises are maintainable and cost-effective.  Architects from big companies are saying "yes they are" right now, but no one thinks their child is ugly.



  • Austin MSDN Code Camp was a huge success - level 000

    This past Saturday, March 4, my user group, ADNUG, hosted its first MSDN Code Camp.  We had some cool sponsors including Microsoft, St. Edward's Professional Education Center, Wrox Press, 101X radio station, CyberJocks, and Catapult Systems

    We had 17 unique sessions from local developers on tracks: Web, Smart Client, Data, and Agile.  My talk was "Pragmatic ASP.NET 2.0:  What features do I need?".  All the sessions got very positive comments on our survey.  We targeted 150 developers, and we hit very close to our goal.  At one point, we thought we were going to be swamped because of the huge number of registrants, but the event went off really well.

    Thanks to all our sponsors for helping make this event a success.
  • Oracle-style joins in Sql server. There is no performance difference - level 300

    I recently came across some sql code that caught me off guard.  Here is is:

    select something
    from table1, table2
    where table1.id = table2.id

    I immediately thought that a Cartesian product was happening and the rows were being filtered afterward.  All my database experience has been with Microsoft databases, so I didn't know that this syntax used to be the way most people did sql..  Like any good engineer, I set out to find out for myself what was really going on.

    I used the Northwind database to compare the following two queries:  the first with Sql server syntax, and the second with "old school" syntax (which Sql server 2000 suppports).
    SELECT    *
    FROM    Orders o
        INNER JOIN Customers c ON o.CustomerID = c.CustomerID
        INNER JOIN [Order Details] od ON o.OrderID = od.OrderID
        INNER JOIN Products p ON od.ProductID = p.ProductID

    SELECT    *
    FROM Customers c, Orders o, [Order Details] od, Products p
    WHERE o.CustomerID = c.CustomerID
        AND o.OrderID = od.OrderID
        AND od.ProductID = p.ProductID

    I ran these two queries many, many times together and in isolation, and I examined the execution plans, the client statistics as well as the Sql trace.  It appears that at a lower level, these two operations are identical.  Both queries took the same Duration, CPU cycles, and Reads to execute.  Here is the Execution plan.  Both queries have this same exact exectuion plan:




    Personally, I like the INNER JOIN syntax.  It's very explicit, and it's easy to add RIGHT and LEFT to dictate OUTER joins.  A plus is that it is the ANSI standard and Microsoft's recommendation for Sql Server. 

    The objective conclusion of this experiment is that the style picked for a query will not affect the speed at which that query runs.  The differences are subjective.  My advice, however, is that a single style be adopted as part of the team's coding standard. 
More Posts

Our Sponsors

Free Tech Publications

This Blog

Syndication

News

Headspring Systems

View Jeffrey Palermo's profile on LinkedIn

See my new blog at .jeffreypalermo.com