Come hang out at the FWDNUG meeting and talk with me about software architecture, object oriented programming and inversion of control on Tuesday April 21st (that's a week from now). 

We'll cover the basics of IOC, but for the most part, this will be an advanced presentation.. lots of code highlighting a few interesting usage scenarios. 

Hope you can make it!

Posted by mhinze | with no comments
Filed under:

Just got this in email:

Our April meeting will not be held on our regular 3rd Tuesday of the month. It will most likely be on the 4th Tuesday - April 22nd. We are awaiting confirmation that our regular meeting location will be available to us on the 22nd. We'll send out the details as soon as they are finalized.

Thought you'd want to see it if you didn't get it.

Posted by mhinze | with no comments
Filed under:

I think the ALT.NET brand is recognizable but awareness is lacking a bit. 

If you've been wondering what exactly is going on, take a look at this short piece in the latest MSDN Magazine by Jeremy D. Miller. And then head to the wiki for more.

I was in Austin in October and I'll be in Seattle in April...

[update] Hanselminutes podcast on ALT.NET with David Laribee 

Posted by mhinze | with no comments
Filed under:

In-house developers (software developers that work for an IT department and not a software development firm) openly condemn their plight of being tasked to design software quickly rather than correctly.

In-house developers rely on environmental certainty. We have a comfortable technical environment.  We have our data sources, our common web services, a monolith HR system, and these things never change

Right?  Never?  ...

Mergers, acquisitions, vendor changes, new technologies, staff changes, user requests, management fiat, budgetary constraints...

To overly rely on your environment is an anti-pattern for corporate developers.

My company was acquired in November by a huge mammoth company that isn't asking questions about why our data sources are useful. Our technical environment is about to radically change.

Fortunately it's not hard to reduce dependencies on certain external services in our applications.  Here is a real-world five-minute example with a scenario should be familiar to most in-house devs.

Interfaces define the implementation

There's a web application.  In it we like to do things with the currently logged in user.  Show data specific to that user, display the user's real name, etc.  We call a web service to get the full name from the login name. I'd wager that almost every moderate-sized company has a "directory" web service like this.

public class GetFullNameService
{
public string GetFullName(string username)
{
string fullname;
// call your web service and get the full name
return fullname;
}
}

Great, wonderful, okay.  But to prepare for an eventual change in environment, we should write an interface so that we can switch out the implementation using dependency injection.

public interface IGetFullNameService
{
string GetFullName(string username);
}

This is useful because my new implementation (the one that will work after the acquisition is complete) is totally different, in fact instead of a web service it uses ADO.NET against OHR.

public class OHRFullNameService : IGetFullNameService
{
public string GetFullName(string username)
{
// use ADO.NET to call OHR
return "full name";
}
}

Since I am programming against an interface and have written a new implementation I can just do a find and replace and change all the GetFullNameService calls to call OHRFullNameService, rebuild, redeploy and ... um, no.

Using dependency injection to swap out implementations

So now we have an interface and two implementations. In the application, we might see something like

public class BasePage : Page
{
private IGetFullNameService _nameService;

public BasePage()
{
_nameService = new GetFullNameService();
}
}

Instead of newing up a concrete type we can use dependency injection to create the instance for us:

public class BasePage : Page
{
private IGetFullNameService _nameService;

public BasePage()
{
_nameService = (IGetFullNameService)
ObjectFactory.GetInstance(typeof (IGetFullNameService));
}
}

Now our BasePage class doesn't care which implementation of IGetFullNameService we use!

Configuring the dependency injection container (StructureMap, in this example) is super easy.  You can set this up to use attributes instead of a configuration file.  But here is a simple, sample StructureMap.config:

<?xml version="1.0" encoding="utf-8" ?>
<
StructureMap>
<
PluginFamily
Type="MyProject.Web.Services.IGetFullNameService"
Assembly="MyProject.Web"
DefaultKey="Default">
<
Plugin Assembly="MyProject.Web"
Type="MyProject.Web.Services.GetFullNameService"
ConcreteKey="Default"/>
<
Plugin Assembly="MyProject.Web"
Type="MyProject.Web.Services.OHRFullNameService"
ConcreteKey="OHR"/>
</
PluginFamily>
</
StructureMap>

Changing the implementation fro GetFullNameService to OHRFullNameService is as easy as changing the DefaultKey attribute of the PluginFamily element to "OHR".

So we've successfully eliminated our dependency on one aspect of our technical environment and we are secure knowing that if our environment changes, we can handle it easily.

So this is just the start down a deep rabbit hole.  There are a few more considerations if you are developing an application using dependency injection that I have omitted from this post.  Fortunately there are resources out there.. a good starting place is Jeremy Miller's blog and my links to DI resources.

I saw a post today about ORMs and how they are hard to use and maintain.  Since we saw ActiveRecord/NHibernate at Ben's talk and we're going to have more talks on ORM tools there may be questions.  I wanted to share my experience and assuage some fears about ORMs that may be holding you up from getting started..

I'm using NHibernate, which does have a learning curve, but it's not as steep as you might think.

Here are one of the criticisms mentioned:

They are not legacy system friendly meaning they are a nightmare to implement

My current project is pulling data from an Oracle 9i database with a schema and data that has been around for 10+ years. I created a few new tables for my stuff and getting set up and relating to the old stuff was painless.

The most unmaintainable thing about the system is all the business rules encapsulated in stored procedures. Fortunately once I got the gist of those rules, which are also enforced in constraints, they were a snap to implement in code.

Real nightmares

What is a nightmare is the previous app that used this data.  I found this method of the Account class used to persist new instances in that old, legacy app:

Public Function Save() As Int32
Dim MyDataAccess As New Legacy.BLL.DataAccess
Dim MyCommand As New OleDbCommand
Dim sb As New StringBuilder
sb.Append("LEGACY_ACCT_PKG.SAVE_ACCOUNT")
MyCommand.CommandText = sb.ToString

MyCommand.Parameters.Add(New OleDbParameter("pACCOUNTID", OleDbType.Numeric, 22, ParameterDirection.Input)).Value = _ID
' ... 20+ more parameters!!! horror!
MyDataAccess.isSetGlobalContext = True
MyDataAccess.RunSP("", MyCommand)
End Function

This is one of hundreds of similar CRUD methods in this app.  Not maintainable.

I don't have a save method in my class, I am using repositories.. the actual "data access" code, common to all the objects I persist is:

public virtual T Save(T entity)
{
NHibernateSession.Save(entity);
return entity;
}

To me that was very easy.  NHibernate handles things for me, I don't have to worry about 20 or 30 of the things that a user of that one old-fashioned method has to worry about. Including all that horrible ADO.NET mess.

Query languages considered harmful?

Here's another criticism:

They require an Intermediary Query Language which means extra work for the programmer

Eh... ok, extra work to learn a query language. Getting the gist of NHibernate's query language takes about 5 minutes.  If you want to explore its intricacies, take an hour to parse the relevant docs.    But writing it is pretty easy!  Here's a simple but typical example of a query to pull back all Projects that a certain Employee is a TeamMember of (think of it as populating a grid on a "My Projects" page):

from Project p join fetch p.Team t where t.Employee = ?

which generates SQL something like:

select * from project 
inner join team on project.id = team.projectid
where team.emplid = :p

Still, there's no requirement that you learn HQL. There are other ways to query: using the Criteria API, straight SQL and in code.  It's okay to decide to avoid pain.

Pain relief

If religion is opium for the masses then object relational mapping would be like Aspirin in the programming world . Not powerful enough to get any programmer high and makes programming easier for about four hours, then real sedation is required to mask the pain. They have even been likened to an unwinnable war in South-East Asia.

This has not been my experience.  What causes me pain is having to deal with the data access myself, or to have queries in my code-behind or worse, in the markup.  It's painful to worry about columns and constraints instead of conceptual relationships and meaning.

Here are some NHibernate resources I found to be really helpful:

Critical to read the documentation
Billy McCafferty's NHibernate Best Practices (I read it four times and it keeps getting better)
Ben Scheirman's NHibernate screencast (very good tips in here)
Setting up NHibernate mapping intellisense
Example application: Cuyahoga CMS source
Example application: CodeCampServer

Posted by mhinze | with no comments
Filed under:

Jon Galloway touched on it in his blog post today:

The best way to learn is to "aspire to be the dumbest person in the room." Being the smartest person in the room is comfortable - you can feel smug and important as you deign to dole out information. It's also the surest way to avoid learning anything. Surrounding yourself with people who are better informed than you are is a great way to keep learning, but it can take away your confidence in what you've got to say.

Wrong solutions:

  • Keep quiet for fear of saying something stupid
  • Keep quiet because all those other brilliant people will probably say it soon, and better

Solution:

  • Don't write for your own ego, write to share information
  • Accept that publishing anything on the internet is one of the best ways to invite constructive criticism for what you think you know

Ah, to invite criticism! To publicly lay intellectually prone with your fleshy bellyful of ideas exposed to the anonymous internet is an incredibly scary thing.

It takes a good deal of confidence to participate online.

On the old altnetconf list, Alex McMahon explains:  He ranks participation online by confidence required

  1. Casual chat with close colleagues
  2. Meeting/workshop with close colleagues
  3. Meeting/workshop with unknowns
  4. Writing on internal blog
  5. Writing on internal blog and actually telling people about it and referring them to it
  6. Writing on internal wiki
  7. Releasing a 'proper' guidance document internally
  8. (4-7 on the internet)

So join a mailing list list, hang out on Twitter, write the blog and participate in the community.  Another way to pitch in is to contribute to open source software.  I've been working on codecampserver, and even though sometimes I feel I am "the dumbest person in the room" the learning experiences, contacts I've made and pure coding thrills have been invaluable.

Posted by mhinze | 1 comment(s)
Filed under:

My friend is a software developer, but he doesn't work for a software company. He works for a home builder, or a pipe manufacturer, or a retailer.  His job is to deliver software, but delivering software isn't the organization's core competency.

This friend of mine is an in house developer haunted by this reality:

You never get to do things the right way. You always have to do things the expedient way ... Once the core functionality is there, the main problem is solved, there is absolutely no return-on-investment, no business reason to make the software any better. So all of these in house programs look like a dog’s breakfast: because it’s just not worth a penny to make them look nice. Forget any pride in workmanship or craftsmanship you learned in CS323. You’re going to churn out embarrassing junk, and then, you’re going to rush off to patch up last year’s embarrassing junk which is starting to break down because it wasn’t done right in the first place.

On the other hand, a comfortable technical environment means he can focus more on building great software for his users and less on the complexities and headache of struggling through technical challenges.

Are you an in house developer?  What anti-patterns do in house developers uniquely face?

Posted by mhinze | 1 comment(s)
Filed under: