On Software Development

This post is part of my “Software Development” series.  The TOC for the entire series can be found here.






Developing good software is hard.  Really hard.  Sure, anyone can buy a book on writing software or pull up some code samples and get something that compiles and runs, but that’s not’s really developing software.  A lot of code in the wild – I’d bet a vast majority of it – just plain sucks.


It’s hard to point out where the blame lies.  It seems that most developers are environmentally or institutionally destined to write bad code. Schools teach how to write code, but not how to architect it or to follow reasonable design practices.  In the zeal for clarity, publishers churn out books, blogs and samples that show bad practices (when is it ever a good idea to access a data model from your UI event handler?).  Managers and customers alike push hard to get things done now, not necessarily done right – only to find months or years later that doing it right would have saved a boatload of time and money.  And let’s face it – many developers are simply showing up to work to pull a paycheck.  You know who they are.  You’ve no doubt worked with them in the past.  You’re probably working with them now.


I was watching Gordon Ramsay the other day and it occurred to me that he and I are alike in our own peculiar way.  I’m not saying that I see myself as the “Gordon Ramsay of Software Development” – hardly –   but we share a common trait.  Just as Gordon gets angry and starts spewing colorful language when he walks into a crap kitchen, it bothers the hell out of me to see complete idiots in my chosen field out there just making a mess of things.  When I see bad code – not necessarily minor errors, or code that could be refactored and made better – but just outright shit code that should not have occurred to a developer in the first place it pisses me off.  By the nature of my work, often getting called in only when the project is off the rails, I see it all the time. Code that, on review, a peer or mentor should have seen and said “Whoa!  There’s no way that’s going into our code base”.  Code that just makes it harder for the next person to do their job.


In an effort to simplify things for my own code, for my customers’ code as well as anyone who is willing to listen to my ravings, I’ve spent a lot of time building, testing, fixing and extending tools and frameworks that many of which I turn around and give away.  This isn’t out of altruism, no, it’s largely because I’m a lazy developer.  I hate writing the same thing twice.  When I start a project, I don’t want to spend large amounts of time building up the same infrastructure that every project needs. Building up a framework for handling UI navigation isn’t what I’d call interesting, but just about every project needs it.  Handling object dependencies and events is common.  Writing a DAL for serializing and deserializing entities is not just drudgery, I find it’s highly susceptible to errors because you end up doing a lot of copy and paste.


I have these cool tools and frameworks that I use in literally every project I work on now.  That’s great for me, but it doesn’t really help others, right?  Without reasonable documentation or explanation, only a small handful of people are going to go through the effort of getting the tools and trying to understand them – even if they are deceptively simple and could potentially save you weeks of effort. 


So I’ve decided to put together a series of blogs over the coming weeks and months that explain, hopefully in simple terms, what these frameworks do, how to use them, and most importantly, why they are worth using.  There’s nothing groundbreaking here.  I didn’t invent some new way to do things.  I’ve simply appropriated other peoples’ ideas and extended them to work in the environments that I work.


Generally I’ll be covering the following topics and frameworks:



  • Dependency Injection and Inversion of Control (using OpenNETCF IoC)
  • Event Aggregation (using OpenNETCF IoC)
  • Plug-in Architectures and interface-based programming (using OpenNETCF IoC)
  • Software features as services (using OpenNETCF IoC)
  • Data Access through an ORM (using OpenNETCF ORM)
  • Parameter Checking (using OpenNETCF Extensions)
  • Exposing data services over HTTP (using Padarn)
  • Whatever else I think of

If there’s a topic you’d like me to talk about, feel free to send me an email.  I may turn on comments here and let you post ideas, but I find that when I enable comments on my blog, I start getting more comment spam than I really want to deal with, so if comments are turned off just drop me a line.

ORM and Custom Object Serialization

Occasionally we need to store data in a database that doesn’t neatly fit into the “normal” column type definitions of a database – for example we might want to store an image or just a serialized object. The newest OpenNETCF.ORM Library provides a simple mechanism for handling these types of objects, it’s just not all that clear from the object model how it works. I’m hoping that this post will clarify things.


First, ORM can handle *any* type of object that is marked as a Field in an Entity class. If the Field is an Object, however, you have to help it out by providing a mechanism to serialize and deserialize that object.


Let’s look at a simple example. Let’s say I have the following Entity definition:

[Entity(KeyScheme.Identity)]
public class TestTable
{
[Field(IsPrimaryKey = true)]
public int TestID { get; set; }

[Field]
public CustomObject CustomObject { get; set; }
}


Sure, it’s likely going to have more fields, but what’s important here is the CustomObject Property that is a CustomObject class. What happens when the ORM library hits one of these when it’s doing an Insert or Select?


If the object boils down to being an object, it calls either a Serialize or Deserialize method, depending on which it needs, in the Entity instance itself. The expectation is that these methods will have the following signatures (yes, I realize these should maybe be defined in some abstract base class, but for now they aren’t):

[Entity(KeyScheme.Identity)]
public class TestTable
{
[Field(IsPrimaryKey = true)]
public int TestID { get; set; }

[Field]
public CustomObject CustomObject { get; set; }

public byte[] Serialize(string fieldName)
{
// serialize
}

public object Deserialize(string fieldName, byte[] data)
{
// deserialize
}
}


What happens here is that a string representation of the Field being requested will be passed in by the framework, and it’s up to your implementation to correctly handle it. Let’s extend this example by defining our CustomObject like this:

public class CustomObject
{
public string ObjectName { get; set; }
public Guid Identifier { get; set; }
public int SomeIntProp { get; set; }

public CustomObject()
{
}

public CustomObject(byte[] data)
{
// deserialization ctor
int offset = 0;

// get the name length
var nameLength = BitConverter.ToInt32(data, offset);

// get the name bytes
offset += 4; // past the length
this.ObjectName = Encoding.ASCII.GetString(data, offset, nameLength);

// get the GUID
offset += nameLength;
byte[] guidData = new byte[16];
// we must copy the data since Guid doesn’t have a ctor that allows us to specify an offset
Buffer.BlockCopy(data, offset, guidData, 0, guidData.Length);
this.Identifier = new Guid(guidData);

// get the int property
offset += guidData.Length;
this.SomeIntProp = BitConverter.ToInt32(data, offset);
}

public byte[] AsByteArray()
{
List buffer = new List();

byte[] nameData = Encoding.ASCII.GetBytes(this.ObjectName);

// store the name length
buffer.AddRange(BitConverter.GetBytes(nameData.Length));

// store the name data
buffer.AddRange(nameData);

// store the GUID
buffer.AddRange(this.Identifier.ToByteArray());

// store the IntProp
buffer.AddRange(BitConverter.GetBytes(this.SomeIntProp));

return buffer.ToArray();
}
}


Notice that I’ve decided to create my own custom serialization routines for the object. You could just as easily use a built-in serializer or whatever you’d like. I’ve put the serialization routines in the custom object class itself to prevent cluttering up my Entity definition. Now the Entity definition get’s fleshed out to look like this for the Serialize and Deserialize methods:

[Entity(KeyScheme.Identity)]
public class TestTable
{
[Field(IsPrimaryKey = true)]
public int TestID { get; set; }

[Field]
public CustomObject CustomObject { get; set; }

public byte[] Serialize(string fieldName)
{
if (fieldName == “CustomObject”)
{
// This will always be true in this case since CustomObject is our only
// Object Field. The “if” block could be omitted, but for sample
// clarity I’m keeping it
if (this.CustomObject == null) return null;
return this.CustomObject.AsByteArray();
}

throw new NotSupportedException();
}

public object Deserialize(string fieldName, byte[] data)
{
if (fieldName == “CustomObject”)
{
// This will always be true in this case since CustomObject is our only
// Object Field. The “if” block could be omitted, but for sample
// clarity I’m keeping it
return new CustomObject(data);
}

throw new NotSupportedException();
}
}


Pretty straightforward, especially if you only have one Object Field to worry about. Once the Serialize/Deserialize methods are implemented in the Entity, the new Entity works just like any other entity in ORM, so you can do something like this to insert a row and retrieve it back:

    var newObject = new CustomObject
{
ObjectName = “Object A”,
Identifier = Guid.NewGuid(),
SomeIntProp = 12345
};

var testRow = new TestTable
{
CustomObject = newObject
};

Store.Insert(testRow);

var existing = Store.Select().First();


I’ve found this to be extremely useful in a project where I had to store spectrum data for a row. Keep in mind that if the object is of any size, it could seriously impact your Select performance since the ORM has to select and rehydrate all of these objects for your returned data set. Use it sparingly, and if the object is often empty, it might pay off to put the custom object into its own child table and pull it in as a relationship so that the Serialize/Deserialize routines only get called when absolutely necessary.

Updates to ORM and IoC projects

We’ve shipped a first version of a customer project.  That’s always good news, but the benefit to the community at large is that updates, improvements and fixes to both the ORM and IoC projects from that project have now propagated to the public code bases.


The IoC changes are pretty minor, which tells me that it’s a pretty robust and mature library on the whole.


ORM had a load of changes in the SQL Compact implementation.  The interface for the DataStore has expanded by several methods due to use-cases I needed methods for and it’s got a whole lot of performance improvements added.  ORM and is now shipping to real-world customers in a handheld product, so I consider it “release” quality.


Be aware that neither project has these changes rolled into a release package yet, so if you want these changes, grab the latest change set from the “Source Code” tab on the appropriate project page.

New ORM Release

I’ve published a new release of the OpenNETCF.ORM library.  Some notable additions are:



  • The ORM can now detect added Entity fields and automatically add the underlying columns to the store

  • A new Select override can now filter result sets by multiple fields

  • I’ve added a skeleton for a SQLite/Windows Phone 7 project with some implementation

If you have a desire to help me get the WinPhone implementation completed, I really could use the extra help.  I’m pretty busy, and without external help on this I don’t see it getting implemented any time soon (unless we get hired to do a WinPhone project of course).


If you’re not up on what the OpenNETCF ORM library is, in short it’s an open-source ORM that actually works on the CF (NHibernate and Entity Framework do not). 

ORM update: Added SQLite assembly for Windows Phone

I’ve made a small update to the ORM library.  I’ve added a SQLite assembly and started implementeing the SQLiteDataStore class.  Note that I say “started” meaning that it’s not done and ready for use (far from it in fact).  I did do a rough pass for store (database and table) creation.  The idea is that it gives at least some seed code for anyone interested in getting ORM up and running on their Windows Phone using SQLite.  If you are interested in doing this, please let me know.  I don’t really have the time to devote to getting this done, so I’m looking for a capable developer who would like to take this on.

OpenNETCF.ORM re-release

I’ve re-released the OpenNETCF.ORM library.  In my haste to port the code out of the production environment I’m using it in back to the Codeplex tree, I missed a file removal.  This broke the Codeplex release and, of course, I didn’t check it before publishing the release.  I’ve rectified the problem and everything in Codeplex should now build.  If it doesn’t send me an email or add a bug to the project to let me know.