# Thursday, May 17, 2007
My little demo/test application that I monkey around with from time to time got a major revamp today.  Nothing fun or exciting, just a lot of infrastructure cleanup that I've been needing to do for some time.  I was hoping this would only take me an hour, but in reality it took me 3 times longer than that.  All I needed to do was:
  1. Upgrade NHibernate from 1.2 beta3 to NHibernate 1.2 GA.
  2. Separate out my shared core library into a separate folder/solution structure.
  3. Stop using GAC'd Castle and NUnit assemblies and use a local libs folder to facilitate building on a clean box.
Nothing fancy, but I ran into some serious issues with log4net.  You would think that because most open source projects use log4net, integration of multiple open source products that use log4net would be a breeze right?  Well, Castle RC2 uses log4net 1.2.9.0 while the latest NHibernate release uses log4net 1.2.10.0.  That seems fine, just add an assembly binding redirect to have castle using the newer log4net version right?  Well that's fine until you realize that the log4net team unexplicablly changed their signed key between those releases, which means you can't use a binding redirect.  Oops, I doubt the log4net team intended that to happen.

To get around this version mismatch I ended having to grab the latest code from the Castle subversion repository which included log4net 1.2.10.0 and build my own assemblies that would play nicely with  NHibernate.

The moral of this story is don't change your keys between versions if they're binary compatiable/incremental updates.  Especially for something so commonly shared as log4net.

.NET | WTF
Thursday, May 17, 2007 10:22:46 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, May 15, 2007
Anyone who's programmed in VB for a while will find this article interesting: http://www.codinghorror.com/blog/archives/000860.html

I didn't realize (or maybe truly understand) VB.NET had a background compiler in Visual Studio 2005 like Eclipse does for Java.  When I was programming in Java/Eclipse the background compiler literally saved me 20 minutes or more a day, its hard to believe C# doesn't have this even in Visual Studio "Orcas". 

The one thing I really from miss from VB is the with statement.  The with statement is very fluent and readable. In C# we could have something like the using statement:

Person user = new Person();
with (user)
{
   .FirstName = "John",
   .LastName = "Doe",
   .Age = 18,
   .PhoneNumber = 5555555,
}

The one thing we will have in .NET 3.5 is property initializers which are pretty close to the with statement, but the one difference is that the with statement would work anywhere.  Property initializers only work on construction of the object and really only save you from having to declare a bunch of overridden constructors.  Property initializers look like this:

Person user = new Person()
{
   FirstName = "John",
   LastName = "Doe",
   Age = 18,
   PhoneNumber = 5555555
}

Now what happens if I need to reuse an instance and assign different values?  Well, hopefully you won't need to, and in likely hood its very unlikely you would.  When I was programming in VB I generally only used the with statement to initialize an object.  What do you think?

Tuesday, May 15, 2007 5:11:50 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, May 04, 2007

I was reading this post by Jeremy Miller and came across this golden nugget of wisdom that seems to be very applicable:

"Oh, and the people out there swearing up and down that giving the business end users a screen to configure a business rules engine themselves will save the day?  BS.  Drawing workflow's with pictures is coding -- with every bit of the risk and danger that coding brings.  Only now you're making noncoders code in the production system.  Think about that last sentence. "

Bingo!  Allow me to elaborate on this:

  • There are no unit tests surrounding the changes, which imply legacy “code”.
  • No verification step.  QA is completely out of the loop, I doubt they would appreciate that.
  • Engineers will need to be brought in to fix problems when something unexpected happens.  This is a reactionary situation which causes people to work over time and under stress, both of which I know I like to avoid.
  • There is no formal change control surrounding the process.  This sounds bad, breaking the law kind of bad.
  • Who wants to code through Visio or some one off custom UI anyway?  Last I checked Visio didn’t have a debugger, and if Visio doesn’t have a debugger certainly your one off custom UI won’t.  Good luck tracking a problem down without full disclosure to the system code and infrastructure.

These issues are not just merely applicable to business rules engines; they are also applicable to highly customizable applications with lots of admin screens.  Do you really want end users to be able to go in and add/remove workflows, user accounts, test points?  Do they really need these features?  Probably not, and this could potentially open up all kinds of data integrity issues.  Who really wants to restore a database from tape because some user made a change they didn’t truly understand?  This is why it’s important to have someone own the change process, like a development team or business rules expert.  Someone needs to be accountable for the integrity of the system.

On top of all this we need to take into account all of the extra work that will need to be done just to create the hellish user interface to the back end of the system.  Add documentation, testing, and training to the mix and you just doubled or tripled your system cost, and what have we gained?  We gained: lots of extra work, bugs, and data integrity issues.

Having the system be highly end user configurable makes the business feel more comfortable because they believe they’ll have ultimate control and flexibility.  Probably a far better solution (and more cost effective) would be to work on your trust issues with the business.  Put them at ease about the system by making them feel like they are part of a cooperative team rather than just a customer.  When release 1 hits they need to know the development will still be there to add additional features and fix any issues that crop up in a timely and predictable fashion.

Friday, May 04, 2007 4:45:32 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, May 03, 2007

In manufacturing wastes are well documented and generally understood, however in software development waste is acknowledged but usually misunderstood, especially by Microsoft Project Project Managers.  In many circumstances (especially in waterfall shops) the common root of all software waste is deemed to come from not planning enough, or not documenting enough.  Basically, all this effort is expended up front trying to ensure that the cardinal sin is not committed.  What is this sin?  Throwing code away. 

In reality we want to throw away code, as much code as possible.  I'm not saying we should generate code just to throw it away, but we should always be looking for opportunities to trim back the code base.  Less code is easier to maintain and test. 

Developers often think through tough business problems and technical problems by coding.  Coding is not just a statement of some requirement, coding is a mental exercise performed by programmers to better understand the problem domain.  It’s through coding we arrive at greater understanding and insight.  Coding allows us to make logical connections between entities, rules, and requirements.  During this research phase should the code be thrown away?  Not necessarily, but in all likelihood all this code will be thrown away as understanding of the problem domain changes over time.

If what I say is true, then throwing away code is not a waste, in fact throwing away code is quite productive.  Waste in software development comes from other areas.  Mary and Tom Poppendieck make the case that waste in software comes from the same areas as manufacturing, however with a slightly different software twist:


Manufacturing                             Software Development


In-Process Inventory          Partially Done Work
Over Production               Extra Features
Extra Processing              Relearning
Transportation                Hand Offs
Motion                        Task Switching
Waiting                       Delays
Defects                       Defects


Thursday, May 03, 2007 5:06:10 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
An entertaining quote from the book I'm reading, "It is better for developers to be surfing than writing code that won't be needed."

They aren't referring to technical spikes or learning opportunities, they are talking about features to a real product.  In other words do option 1*, its cheaper.  Adding unneeded features to your code base will cost you more money over the lifetime of the product than paying the developer to do nothing at all.  Each feature you add complicates the code base making each additional change more costly.

* There are always 3 options to any decision, and option 1 is always "do nothing."

Thursday, May 03, 2007 4:33:33 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, May 02, 2007
Right now I'm reading Implementing Lean Software Development by Mary and Tom Poppendieck, and something about the Toyota Production System caught my eye.

"Both Toyodas had brilliantly perceived that the game to be played was not economies of scale, but conquering complexity."

I translate this to mean, RAD code generated goo from Visual Studio versus elegant loosely coupled code based solutions (the kind most often found in OSS).

Wednesday, May 02, 2007 9:49:24 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
Thank you Google for providing with all kinds of useless, but entertaining, information.  From the Urban Dictionary...


A sneal is not quite a snack, nor is it quite a meal. A sneal lies somewhere in between the two, and snealing is most commonly practiced by college students. When confronted with the question of what the healthiest methods of eating are, it has been said that regular "snealing" is more beneficial to the individual than regular "mealing." A sneal, in most cases, is equivalent to 2/3 of a meal (This also means that 2 sneals equals roughly 1 1/3 meals).
To date, the most common snealing plan involves a regular breakfast, a regular lunch, and two sneals in the evening (one typically at 5 p.m., the other typically at 8 p.m.). Though the average "snealer" eats two sneals a day, it is quite possible, and perhaps more beneficial, to eat three in a single day to support the growing minds of college students.
Another part of the sneal involves 2 - 8 oz. glasses of the choice beverage. Though milk is encouraged to be at least one of these drinks, it is not absolutely necessary for a healthy sneal.

If we sneal now at 5:30, we will still have time for another one before the cafeteria closes.


Wednesday, May 02, 2007 5:40:56 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
HTML textarea controls do not support the maxlength attribute like the text input control.  Doh!  The nice easy way around this is to add an ASP.NET regular expression validator with the following regex: ^[\s\S]{0,25}$

The only slight problem with this approach is that it is possible to input more than X number of characters, but the validator will display an error and disallow the page to be submitted.

Wednesday, May 02, 2007 5:33:01 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, April 26, 2007
Here are two sources of documentation for Rhino Mocks:

Articles

Documentation

Thanks Ray!

Thursday, April 26, 2007 9:01:05 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
I converted my main .NET solution I'm working on from Visual Studio 2005 to Visual Studio Orcas without any problems.  I did the conversion so that I could play around with LINQ, and more specifically the LINQ to NHibernate adapter, and as such I chose to run everything under .NET 3.5.

I thought for sure I would get at least one conversion error or compiler error, but no.  My solution even included NHibernate and Iesi.Collections.  Better yet and possibly even more suprising is that I can still run and debug the web project which is using MonoRail RC2.


Thursday, April 26, 2007 3:57:26 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, April 24, 2007
I was going to use the NHibernate facility provided by Castle Windsor until I found out it didn't support using class mapping attributes.  I ended up rolling my own implementation but added a couple new features to my implementation:

  • Automatic context aware session container (web context or thread local).
  • Ability to use NHibernate mapping attributes instead of hbm.xml files.
  • Can use the built-in .NET 2.0 connectionStrings element to specify an NHibernate connection string.
I think the first two items are pretty obvious, but the last feature I added because most standard .NET applications make use of these elements - for better or worse.  I think its a good idea to be consistent if possible.  Additionally this would allow any standard .NET administration tool to examine and edit the connection string for the application.

I also wanted the ability to use a custom configuration section so that I could add additional elements and attributes as needed.  The configuration section handler produces a SessionFactoryConfiguration instance, which itself it a subclass of NHibernate.Cfg.Configuration.  The configuration section looks like this:

  <sessionManager>
    <settings>
      <setting name="hibernate.dialect">NHibernate.Dialect.MsSql2000Dialect</setting>
      <setting name="hibernate.connection.driver_class">NHibernate.Driver.SqlClientDriver</setting>
      <setting name="dotnet.connection_string">Laptop</setting>
      <setting name="hibernate.connection.provider">
         NHibernate.Connection.DriverConnectionProvider
      </setting>
    </settings>
    <resources>
      <resource assembly="Sneal.Northwind.Core" useAttributes="true"/>
    </resources>
  </sessionManager>

Notice the setting dotnet.connection_string.  This is the custom hook I added to my custom configuration handler that resolves Laptop to the .NET connection string named Laptop:

  <connectionStrings>
    <add name="Laptop" connectionString="Database=Northwind; Data Source=.\sqldev2000;" />
  </connectionStrings>

Then I just wire up my SessionManager instance to my Repository instance using an IoC container; currently Windsor.  I have an HttpModule which handles my Unit of Work currently, but unfortunately its tied to Windsor and my current application, so now I'm off to decouple it for reuse.
 

Tuesday, April 24, 2007 5:26:12 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Sunday, April 22, 2007
Adding to my previous post, I thought I would also add an example that uses the new LINQ query expression syntax.  The example is pretty much the same as the last, except that I added one additional person to the list and added an aggregate.

public static void DotNet35WithQueryExpresion()
{
    IList<Person> people = new List<Person>()
    {
        new Person() { Age = 28, FirstName = "Shawn", LastName = "Neal" },
        new Person() { Age = 16, FirstName = "Isabella", LastName = "Neal" },
        new Person() { Age = 15, FirstName = "Joe", LastName = "Velope" },
        new Person() { Age = 43, FirstName = "John", LastName = "Smoe" }
    };

    IEnumerable<Person> teens = from p in people where p.Age < 20 && p.Age > 12 select p;
    Console.WriteLine("The following people are teenagers:");
    teens.WriteAll();

    int sumOfAges = teens.Sum(p => p.Age);
    Console.WriteLine("Sum of all ages: {0}", sumOfAges);
}

Looks like I just wrote some statically checked SQL straight into my c# doesn't it?  Seeing how Ayende has declared that queries are a business concern (and I agree) and we now have LINQ, we can finally place our queries where they belong, in our domain/service layer or even our presentation layer.  You could put your queries there before, but the legions of Microsoft followers would cry out, "This is not the MS way!"  It should be much easier to convince the Microsoft drones that still insist on putting business logic in the database, i.e. stored procedures, that queries in fact belong in the application under unit test.  Yes, queries should be unit tested just like the rest of your application!  Remember that queries are business logic.

I'm still not sure if there is a LINQ query expression that I can apply in this scenario that would replace the lambda expression in the Sum function.  Any idea?

Saturday, April 21, 2007 11:20:16 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Saturday, April 21, 2007
I finally downloaded and installed Visual Studio "Orcas" beta 1 so that I could start playing around with the new functionality built-in to .NET 3.5.  I wanted to build a sample that compared an implementation between .NET 1.1, .NET 2.0, and .NET 3.5, here's the contrived example that I came up with based on a series of postings by Scott Guthrie.

Each example is making use of a simple POCO, note that in .NET 3.5 the private variables and public properties could be replaced by automatic properties.

public class Person
{
    private string firstName;
    private string lastName;
    private int age;

    public Person() { }

    public Person(string firstName, string lastName, int age)
    {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }

    public override string ToString()
    {
        return String.Format("{0} {1} - {2}", FirstName, LastName, Age);
    }

    public string FirstName
    {
        get { return firstName; }
        set { firstName = value; }
    }

    public string LastName
    {
        get { return lastName; }
        set { lastName = value; }
    }

    public int Age
    {
        get { return age; }
        set { age = value; }
    }
}


The .NET 1.1 implementation is pretty terse, and requires the most work on the part of the developer.  Although I think it reads horribly, pretty much any developer (even Mort) can understand exactly what the code is doing.

public static void DotNet1()
{
    ArrayList people = new ArrayList();
    people.Add(new Person("Shawn", "Neal", 28));
    people.Add(new Person("Isabella", "Neal", 16));
    people.Add(new Person("John", "Smoe", 43));

    ArrayList teens = new ArrayList();
    foreach (Person person in people)
    {
        if (person.Age < 20 && person.Age > 12)
            teens.Add(person);
    }

    Console.WriteLine("The following people are teenagers:");
    foreach (Person o in teens)
        Console.WriteLine(o.ToString());
}

In .NET 2.0 things become easier for the developer with anonymous delegates and the new generic List implementation.  The only problem is that the syntax doesn't flow well and Mort might not get it, but at least the nasty foreach statement is gone.

public static void DotNet2()
{
    List<Person> people = new List<Person>();
    people.Add(new Person("Shawn", "Neal", 28));
    people.Add(new Person("Isabella", "Neal", 16));
    people.Add(new Person("John", "Smoe", 43));

    List<Person> teens = people.FindAll(delegate(Person p) { return p.Age < 20 && p.Age > 12; });
    Console.WriteLine("The following people are teenagers:");
    foreach (Person o in teens)
        Console.WriteLine(o.ToString());
}

Things in .NET 3.5 become a whole lot cleaner and elegant.  The people.Add() statements are replaced by much cleaner object initializers.  I also used the object initializer syntax for each person instance, even though I provided an overloaded ctor; in .NET 3.5 I could actually forgoe the overloaded ctor.  The most interesting part is that the List.FindAll has been replaced by a LINQ Where extension method with a lambda expression argument - compare that to the .NET 1.1 implemetation!  The final bit is that I added my own WriteAll() extension method just for fun.

public static void DotNet35()
{
    IList<Person> people = new List<Person>()
    {
        new Person() { Age = 28, FirstName = "Shawn", LastName = "Neal" },
        new Person() { Age = 16, FirstName = "Isabella", LastName = "Neal" },
        new Person() { Age = 43, FirstName = "John", LastName = "Smoe" }
    };

    IEnumerable<Person> teens = people.Where<Person>(p => p.Age < 20 && p.Age > 12);
    Console.WriteLine("The following people are teenagers:");
    teens.WriteAll();
}

public static class MyExtension
{
    public static void WriteAll(this IEnumerable enumerable)
    {
        foreach (object o in enumerable)
            Console.WriteLine(o.ToString());
    }
}

I'm now thinking of using .NET 3.5 on my current pet project - LINQ and extension methods are absolutely fantastic!


Saturday, April 21, 2007 4:40:08 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  |