Blake & Duane, welcome to Headspring!

I'd like to publicly welcome Blake Caraway and Duane DeRouen to Headspring Systems.  We're very glad to have them both.

Duane comes on board as VP of Client Services.  I'm confident Duane will be an asset to account management and client satisfaction.

Blake joins us as a Senior Consultant.  Blake brings lot of enterprise software experience including an SOA focus.

Learning NHibernate? Join the email list with 600 other users

When Bil Simser started the nhusers Google Group, I joined, but I wasn't sure how much traffic it would get since the NHibernate forum doesn't have a whole lot of answers to questions.  It's still going steady, but this nhusers Google group has really taken off.  WOW, am I pleasantly surprised!  There are over 2000 messages in this fairly new group.  Just searching the archives will probably help you solve any problems you are having with NHibernate.

Join, post a question, and participate in community.

Going lean in Visual Studio (even more than Jimmy!)

Jimmy Bogard appropriately points out that Visual Studio gets really cluttered with toolbars that rarely get used.   It's more productive to keep your hands on the keyboard, so that leaves little mousing.  Even moving around the solution explorer doesn't really require the mouse.  So these toolbars just take up space.

There is an option in Tools > Options where you can nuke the navigation drop-downs at the top of the window.  After all, how often do you use them.  If your classes are small the answer is probably never.  If you use Resharper (CTRL+F12) the answer is probably never

 

The bottom checkbox is "Navigation bar".  Unchecking this option will make the pesky drop-downs at the top go away.  The below screenshot is how I roll.

To answer Javier's question (comment below), yes, I also turn off animation.  When you need to work quickly, animation is annoying.  I just want things to happen as quickly as possible.  Visual Studio, Windows, anything.  Animation distracts.

Kevin Hurwitz is blogging!

Kevin Hurwitz has posted his first blog post.  Kevin is another insanely intelligent person, and I'm fortunate to work with him.  Stop what you are doing right now and subscribe to his feed.

I'll get to your application in a minute - First, we need to build the framework

Today at lunch, I had a conversation with Kevin Hurwitz about developer tendencies.  Kevin related a project he consulted on.  He came in after over a million dollars had already been spent by the client, and he found the following:

  • Not a single feature had been delivered (save a few half-finished screens)
  • The team had spent all the time creating an application framework that, when finished, would make the application practically create itself.
  • The development manager was the one who instigated the framework frenzy, and was eventually fired.

 

Clients typically engage us for actual software.  A client isn't interested in software that can be used to create software (frameworks).  They have a problem, and a software system can help them solve the problem. 

I, along with Kevin, have encountered the common mindset of falling from application mode into framework mode.  I find it's common with really smart programmers who take pride in their technical ability.  Creating frameworks is fun because the programmer is the customer of the framework.  Writing software for yourself can be more fun than writing software for someone else.  Writing a framework is writing software for yourself.  On a client's dime, this is typically not acceptable. 

The customer needs to see the software come to life before his eyes.  Every week, the customer need to see new features working. 

Playing devil's advocate:  _If_ it were possible to create the magic framework that would make the application practically write itself, communication is key, and it's a bet, a strategy, an approach.  If this were possible, and you'd successfully done it time and time again for many clients, then it should be discussed with the client beforehand.  Ultimately, the framework becomes property of the paying client, so the client ought to know what is happening, and the client needs to be ok with it.

Back to reality:  Frameworks are better harvested from several applications that ended up using similar patterns.  Writing a framework before an application is BDUF (big design up front).  There are so many assumptions that go into the framework that some of them are bound to be wrong.

The real, repeatable satisfaction.  With many programmers preferring framework development, a client-centered process can bring joy in working on the client's application.  Delivering new builds of the software frequently will please the client, and that level of customer service brings satisfaction back the other way.  There is nothing better than an elated client who loves what he sees unfolding before him.

What about all the common junk that the application needs?  Chances are that there are already libraries that satisfy your needs.  Data access. logging, authentication, caching, indexing, builds, UI controls, etc.  There are both commercial and open-source offerings that make great buy vs. build decisions.  For the needs that don't have offerings yet, do it first, then when the exact same need comes up again, it will be easy to create a library that satisfies this common need now that you know _exactly_ what the need is.  Then, the library or framework can be created _without assumptions_ because you have experience to back up the uses.

For more, you can subscribe to my feed:  http://feeds.jeffreypalermo.com/jeffreypalermo

PDC 2008 Party with Palermo - Save the date!

Party with Palermo will be coming to L.A. for Microsoft's Professional Developers' Conference.  Save the date:  October 26, 2008 at 7:00 PM.

Jeremy Miller on O/R Mapping

Jeremy Miller was recently on the ALT.NET Podcast discussing O/R Mapping with Ward Bell.  Jeremy is one of those guys who is insanely intelligent.  I listened to the podcast, and I recommend that you do as well.

It's not the client's job to know what he needs - It's our job to find out

While I was at Tech Ed 2008, I was a guest on a Software Quality panel hosted by the .Net Rocks crew, Carl Franklin and Richard CampbellDavid Platt said something that I really love (and I'll paraphrase).  David gave the analogy of a doctor and a patient. 

We go to a doctor because we think we have a medical need and we need an expert to consult with and a provide a solution to what is ailing us.  The doctor listens and asks questions by which to formulate some possible solutions to the problem we present.  The doctor doesn't expect us to even be able to talk in the language of medicine.

In software, we can't expect our clients to know what they need.  Much like the depth of a patient may be "I need to get rid of this infection" or "Give me some pills.  I'm in pain".  Our clients know what is causing them pain, in the business sense, so the problem is from that experience perspective.  Some clients might go so far as to ask for some "pills", that is, they might ask for a specific software system that is assumed to solve the problem. 

It is the our job to listen and ask pointed questions to determine need.  Being software experts, we must also know how to ask the right questions to flesh out the need.  If the clients asks for something specifically, and we deliver, but that delivery doesn't solve the pain, it's our fault.  If I ask my doctor for a specific pill, he prescribes it, then I'm still in pain, it's the doctor's fault for allowing me to drive diagnosis.  We, as software professionals, are on the hook for responsible analysis that ensures any solution we provide adequately addresses the root of the problem at hand.

The client can't tell us what he wants.  It our job to find out.  A required skill of any consultant at Headspring is analysis.  Analysis is something underrated, but analysis ensures we build the right thing.  The risk of building the wrong thing is so great that we can not afford it.  Building (prescribing) the wrong thing would be disaster for our reputation.  Analysis is what ensures we build the right thing.

July Agile Boot Camp filling up quick - reserve your spot now


On July 23, 24, and 25, I will be teaching another Agile Boot Camp in Austin, TX.  The Agile Boot Camp is software engineering training for .Net developers.  Unlike most training courses about programming, this class doesn't focus on particular technologies or APIs.  This course is all about practices.  The students in the class make up a software team for the duration of the course, and together, we leverage all the practices in Extreme Programming as we extend a real-work enterprise application. 

Visit the training website to read more details: http://c2.com/cgi/wiki?ExtremeProgramming

See what others have said about the course:

Lee Brandt:

"Man! we actually covered a lot! Jeffrey did a great job of making it seem like not much, but when I got back and started telling my boss about it, there were just TONS of things to talk about. We talked about Team Estimation and Design, NHibernate Mappings, Test-Driven Development, Domain Driven Design, Automated Builds and on and on and on. I have absolutely no idea how we managed to cram all that stuff in three days, but we did."

Karthik Hariharan (Telligent):

"While a lot of software development training is often presented very academically, Headspring's was very hands-on and really pushed everyone to pick up the processes and tools very quickly, just as you would in the real world."

J. Michael Palermo IV:

"This was an excellent training event, and I plan to steal be inspired to use some of his methodologies at Interface Technical Training."

Brad Mellen-Crandell
Rapidparts Inc.

"This was the best technical training course I've been to, period. No fluff here. The course was packed with information and best practices that I could start implementing immediately when I got back to work on Monday."

Ken Jackson
Catapult Systems

"Jeff is an excellent teacher and practitioner of Agile principles and methods. His integration of open source tools to boost productivity will surely help me be more successful and confident in my daily working regimen."

Use this NHibernate wrapper to keep your repository classes simple

It's no secret that we at Headspring Systems use NHibernate for data access in the custom software systems we deploy.  I, personally, have been using NHibernate since 2005 when version 0.8 was current.  Now, we're approaching the 2.0 version, which I'm very excited about.  With version 2.0, NHibernate will be mostly on par with Hibernate 3.2.

If you are just getting started with NHibernate, some of the first questions you'll need to answer are:

  • How do I configure NHibernate?
  • How do I manage the session factory?
  • When do I create and throw away sessions?

The answers are different based on the context.  If you have a smart client application, you'll need to decide what size you want your units of work (I suggest they be small).  You'll need to create a new instance of ISession for each unit of work and Dispose() of it at the end after commiting the transaction.

It seems the majority of enterprise applications these days are web applications, and since I run a .Net shop, we use ASP.NET.  The unit of work is easy here.  We have one web request be one unit of work.  We create an instance of ISession at the beginning of the web request and dispose of it at the end.

I've created several wrappers for NHibernate over the years, and I think they have improved as my understanding of NHibernate has increased.  Ironically, the wrapper started out much more complex than it is today.  I've simplified it over time, and now, I think I've gotten it down to its simplest essence.

The following is a class called HybridSessionBuilder.  It is appropriate for ASP.NET applications using NHibernate, and you can see it in action in the CodeCampServer codebase.  There is a version that supports multiple databases within the Tarantino project (sometimes you can't have just one).

The key to this is the interface:

using NHibernate;
using NHibernate.Cfg;

namespace CodeCampServer.DataAccess
{
    public interface ISessionBuilder
    {
        ISession GetSession();
        Configuration GetConfiguration();
    }
}

Repository classes should require an instance of ISessionBuilder passed into their constructors, and for each operation, they should call GetSession().  GetConfiguration is there to facilitate SchemaExport, which we use to generate the database schema from the NHibernate mappings.

Below is the HybridSessionBuilder class.  Feel free to use it in your applications.

using System.Web;
using CodeCampServer.Model;
using NHibernate;
using NHibernate.Cfg;

namespace CodeCampServer.DataAccess.Impl
{
    public class HybridSessionBuilder : ISessionBuilder
    {
        private static ISessionFactory _sessionFactory;
        private static ISession _currentSession;

        public ISession GetSession()
        {
            ISessionFactory factory = getSessionFactory();
            ISession session = getExistingOrNewSession(factory);
            Log.Debug(this, "Using ISession " + session.GetHashCode());
            return session;
        }

        private ISessionFactory getSessionFactory()
        {
            if (_sessionFactory == null)
            {
                Configuration configuration = GetConfiguration();
                _sessionFactory = configuration.BuildSessionFactory();
            }

            return _sessionFactory;
        }

        public Configuration GetConfiguration()
        {
            var configuration = new Configuration();
            configuration.Configure();
            return configuration;
        }

        private ISession getExistingOrNewSession(ISessionFactory factory)
        {
            if (HttpContext.Current != null)
            {
                ISession session = GetExistingWebSession();
                if (session == null)
                {
                    session = openSessionAndAddToContext(factory);
                }
                else if (!session.IsOpen)
                {
                    session = openSessionAndAddToContext(factory);
                }

                return session;
            }

            if (_currentSession == null)
            {
                _currentSession = factory.OpenSession();
            }
            else if (!_currentSession.IsOpen)
            {
                _currentSession = factory.OpenSession();
            }

            return _currentSession;
        }

        public ISession GetExistingWebSession()
        {
            return HttpContext.Current.Items[GetType().FullName] as ISession;
        }

        private ISession openSessionAndAddToContext(ISessionFactory factory)
        {
            ISession session = factory.OpenSession();
            HttpContext.Current.Items.Remove(GetType().FullName);
            HttpContext.Current.Items.Add(GetType().FullName, session);
            return session;
        }
    }
}

NHibernate will automatically look for a file in the current AppDomain's base location named "hibernate.cfg.xml".  This file in CodeCampServer is the following:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration  xmlns="urn:nhibernate-configuration-2.2" >
    <session-factory>
        <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
        <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
        <property name="connection.connection_string">Data Source=localhost\sqlexpress;Initial Catalog=CodeCampServer;Integrated Security=True</property>
        <property name="show_sql">false</property>
        <property name="dialect">NHibernate.Dialect.MsSql2005Dialect</property>

        <property name="query.substitutions">true 1, false 0</property>    
        <mapping assembly="CodeCampServer.DataAccess" />
    </session-factory>
</hibernate-configuration>