# Tuesday, July 20, 2010

Codeplex recently updated the server hosting the IoC project to TFS10.  Since we still have to use Studio 2008 for device development, I had to do some client changes for bindings to get to the server.  TFS 2010 added the concept of a "Team Project Collection", which Codeplex is using - but Studio 2008's Team Explorer dialog has no provision for it.  It took me a while with a search engine to figure out how to actually attach - basically you have to manually type the full path into the connection dialog in Team Explorer like so:

http://<serverName>:<port>/<vdir>/<collectionName>

So for the new TFS10 on Codeplex, it looks like this:

https://tfs.codeplex.com:443/tfs/tfs10

Tuesday, July 20, 2010 10:46:45 AM (Central Daylight Time, UTC-05:00)  #     | 
# Monday, July 12, 2010

One drawback to the OpenNETCF.IoC framework was the difficulty in making object generation loosely coupled.  This is especially true when object types you want to create change depending on your runtime environment.  For example let's say we have an interface IAccelerometerService.  Different devices have different implementations, and the emulator and your integration tests don't even have hardware so they need a simulator.  So you create some classes that derive from the interface like this:

public interface IAccelerometerService
{
}

public class DeviceAAccelerometer : IAccelerometerService
{
// handles the accelerometer by using APIs for device A
}

public class DeviceBAccelerometer : IAccelerometerService
{
// handles the accelerometer by using APIs for device B
}

public class SimulatedAccelerometer : IAccelerometerService
{
// simulates an accelerometer (emulator, test use, etc)
}

That's all well and good, but let's say we have a generic infrastructure module that does the object creation and injection.  We don't want it to have to know about the concrete class types. They might be in separate assemblies that may not even exist - you certainly don't need (or want) to ship emulator implementation for your hardware. 

How would you handle this? The IoC framework doesn't like the following construct:

RootWorkItem.Items.AddNew<IAccelerometerService>();

Because it has no idea what concrete type you want it to create.  In this case it will throw an IOCException.

Today I added a "registration" process to the framework.  You now can do the following:

RootWorkItem.RegisterType(typeof(SimulatedAccelerometer), typeof(IAccelerometerService));

This tells the RootWorkItem that when you call to create an item of type IAccelerometerService, it should actually create an object of type SimulatedAccelerometer.

Each ManagedObjectCollection (so Items, WorkItems, SmartParts and Workspaceas) keeps track of its own Dictionary of type mappings and calling RegisterType on a given WorkItem calls the registration for each.  You can explicitly call RegisterType on any one of the collections directly and "override" an existing registration.  This means that you could have Items create one type and SmartParts create another type for the same interface.  I'm not sure when you'd ever want to do that, but I've provided for it.

Hopefully this makes the IoC framework a little more friendly, especially for testing (which is already painful enough for devices), and helps you, as a developer, develop your solutions faster without having to think about the underlying framework.

Monday, July 12, 2010 5:37:14 PM (Central Daylight Time, UTC-05:00)  #     | 

Codeplex is in the process of upgrading their servers to TFS2010.  It isn't very clear, however, how to attach to the upgraded servers from older versions of Studio (like Studio 2008, which is required for all device development).  The answer is that you have to install a "forward compatibility update".

Monday, July 12, 2010 11:58:02 AM (Central Daylight Time, UTC-05:00)  #     | 
# Wednesday, June 30, 2010

I've written about your DWR before.   While deleting code is certainly a way to increase it, it's not really the entire point.  The real point is that you should be writing less code.  I'm a huge fan of writing less code - especially less of the redundant, mind-numbing, why-can't-I-hire-an-intern-to-write-this code.  You know what I'm talking about - all of that data access layer garbage that we churn out to get our class data into and out of our relational databases.

If your job is primarily working on one application, you probably don't do this a whole lot, but when you are frequently starting new projects, you find yourself getting into this tedious stuff frequently, and I really, really hate doing it.  Not only is it torture, it's highly prone to errors since it's typically a copy, paste and adjust-the-names process.  How often have you have to write code to generate your database?  Does code like this look familiar?

public Book[] GetAllBooks()
{
  var books = new List<Book>();

  using (SqlCeCommand cmd = new SqlCeCommand("SELECT * FROM Book", Connection))
  {
    using (var results = cmd.ExecuteResultSet(ResultSetOptions.Insensitive))
    {
      while (results.Read())
      {
        if (m_bookOrdinals.Count == 0)
        {
          for (int i = 0; i < results.FieldCount; i++)
          {
            m_bookOrdinals.Add(results.GetName(i), i);
          }
        }

        books.Add(new Book
        {
          BookID = results.GetInt32(m_bookOrdinals["BookID"]),
          AuthorID = results.GetInt32(m_bookOrdinals["AuthorID"]),
          Title = results.GetString(m_bookOrdinals["Title"])
        });
      }
    }
  }

  return books.ToArray();
}

Well, I finally got tired of it and decided to spend some time writing code that would free me from having to do that stuff any longer.  The result is a new, open-source project called the OpenNETCF.ORM Framework.  It's a simple, lightweight ORM that helps take care of this tedium.  For example, the above block of code now looks like this:

public Book[] GetAllBooks()
{
  return Store.Select<Book>();
}

And it pulls all of the books from the underlying SQLCE database. Yes, it's that simple.  Of course getting it to do that requires a little infrastructure work.  For this one the Book class has to look like this:

[Entity]
public class Book
{
  [Field(IsIdentity=true, IsPrimaryKey=true)]
  public int BookID { get; set; }

  [Field]
  public int AuthorID { get; set; }

  [Field]
  public string Title { get; set; }

  [Field(SearchOrder=FieldSearchOrder.Ascending)]
  public BookType BookType { get; set; }
}

But that's a small price to pay in my book.  We went from 11 lines of code (not counting brackets) to one.  Multiply that out by the number of entities, filtering logic, paging logic and all the other code you typoically write and you'd greatly decreased your LOC count.

Now I'm not saying that OpenNETCF.ORM does everything that something like the Entity Framework does.  Remember, this is a small scale framework (the core is only 14k and the SqlCE implementation adds 17k) designed for mobile and embedded systems.  It's also put together by a team of one and as a side project while doing other work.

What it does have, though, is performance. It's actually faster than using direct SQL calls in many cases because it avoid the query processor whenever it can).  It has extensibility. The source code has a full implementation for SQL CE but I've also included the skeleton for an XML implementation for anyone who wants to try their hand at it, and it would be pretty easy to do a MySQL or SQLite implementation as well.  Most important, though, is that it has my commitment.  Like the IoC framework, I've already rolled ORM into a production application.  That means that as I find problems, they are going to get fixed.  As I find features that are missing that would help me get my job done, I'm going to add them.  Bottom line is that this is not a science project that I'm doing purely for fun and that will get abandoned when I get bored with it.

So if you're as tired of writing DAL code as I am, give it a try.  If you like it, let me know, or better yet update the docs or a new implementation.

If you're ready to get started, pull down the latest code (there are no releases quite yet) and look at the test project.  There should be enough to get you going on how to use it, but if you have questions, feel free to post them.

Wednesday, June 30, 2010 10:54:38 AM (Central Daylight Time, UTC-05:00)  #     | 
# Thursday, June 24, 2010

Several years ago, a coworker of mine made a statement that I still consider pretty profound.  To paraphrase, he said that his career goal was, over his lifetime, to delete more code than he wrote.

It’s a simple statement that at the time I thought was a pretty good idea – after all we were about a year into coalescing a whole load of separate code bases into a single one and we’d already done a lot of slashing of redundant stuff.  But the more code I write and the more I think about it, the more I think that his goal is nothing short of software genius that we should all strive to achieve.

I'm going to call the measurement of this goal a developer's Delete-Write Ratio, or DWR, calculated quite simply as [lines deleted]/[lines written].  If you do a lot of deleting, it's going to be > 1.  If you do more writing you're going to have a DWR < 1. 

I imagine that over the span of a career the number is going to start really low as a fresh developer who thinks he knows everything but really knows close to nothing and then creeps up as you gain knowledge. I'm also willing to bet that very few developers ever reach a value of 1.0, so if I achieve even close to a 1.0 DWR I'll be really happy.

Of course when you spend a majority of your time working in an existing code base, it’s usually a lot easier to find “opportunities to delete” than when writing new code.  Since a large amount of what I seem to write is from the ground up it’s difficult to keep my short-term DWR above one.  I’d propose that developers who are primarily writing new code should amend their goal to make it as difficult for the next developer to achieve a DWR above 1 as possible.

What that means is that, as a developer, you need to justify the existence of the code you write.  This doesn’t mean you need to write cryptic code that others can’t read but it does mean that the code you write needs to have purpose.  If two sections of code have the same or similar purpose, then you’re making it easy for someone else to refactor and raise their DWR.

So what can we, as developers trying to make our way through our projects and meet the deadlines foisted upon us?  There are the easy things, like using existing code instead of reinventing the wheel and constantly looking for opportunities to refactor not just existing code but also code as we write but more important is to discipline ourselves.  Don’t give in to schedule pressures that make you think that copying that code file and making a few tweaks will get you toward your goal.  Use inheritance and base classes or refactor to a generic.

Any time you find yourself using copy-and-paste a big red flag should go up.  In fact, I think an awesome Visual Studio add-in that would aid code quality would be something that prevents copying and pasting any more than 2 lines of code at a time.  Seriously, if you are pasting more than a couple of lines of code, it’s very likely that you’ve got an opportunity to refactor.

Even though our lives revolve around the code we write (at least our lives with respect to our jobs), code really is the enemy.  The more code you have, the more bugs you have and the higher your support costs.  Obviously the perfect, utopian-as-unicorns software would be that which meets all of your customers' needs and takes zero lines of code to do so.  Until we figure out how to work that kind of magic, though, we have to settle for less-than-perfect and lay down some code.  But when you're writing that code ask yourself, "what is this doing to my DWR?"

Thursday, June 24, 2010 5:39:39 PM (Central Daylight Time, UTC-05:00)  #     | 
# Monday, June 14, 2010

I just checked in another update to the OpenNETCF.IoC framework.  If you've used the framework for event aggregation you're probably aware that an EventSubscrition can set the ThreadOption to "UserInterface" but that had no effect.  We'll I've fixed that - at least partially.  Up until now I couldn't figure a way to wire up any arbitrary delegate without the availability of Emit. Today I had the idea that implementing a known subset could be done without Emit, but instead hard-coding a class into the framework that handles doing the Invoke call to get the event into the proper context.  Now if your event handler is of type EventHandler or, more importantly, EventHandler<T> (meaning that if you use the GenericEventArgs already present in the framework, you're all set), you don't have to call InvokeRequired and Invoke any longer - the framework handles it for you (and I really wish I'd done that 6 months ago - would've saved me a lot of headache).

Monday, June 14, 2010 6:10:10 PM (Central Daylight Time, UTC-05:00)  #     | 

Microsoft has been very quiet for the past few years with regards to the Windows CE OS and this has lead to quite a bit of speculation about the demise of the OS.  Since the OS is still the underpinning of both Zune and the upcoming Windows Phone 7, it's hard to imagine that the OS is going away but the rumors persist.  It certainly doesn't help that Microsoft was long silent on the matter (and even what they have finally said is pretty nebulous) or that they still haven't given us any clear indication of what the development story is going to be.

One new bright spot that indicates their commitment to the platform as a general embedded offering is their new posting of a job position for an Technical Evangelist for the platform.  This is *not* a position for espousing WinPhone or Zune, but purely Windows CE (or Windows Embedded Compact if you prefer the newer marketing spin).

Maybe this signals a new ramp-up and commitment to us lowly, knuckle-dragger embedded developers.  Once can hope anyway.

Monday, June 14, 2010 12:25:17 PM (Central Daylight Time, UTC-05:00)  #     |