# Monday, September 17, 2012

I’ve recently started refactoring a customer’s code base for a working application.  They recognize the need to make their code more extensible and maintainable so I’m helping to massage the existing code into something that they will be able to continue shipping and upgrading for years to come without ending up backed into a corner.

One of my first suggestions was to start eliminating the abundance of static variables in the code base.  In this case, static classes and methods abound, and it looks like it was used as a quick-and-dirty mechanism to provide singleton behavior.  Now I’m not going to go into depth on why an actual singleton might have been better, or the pitfalls of all of these statics.  Write-ups on that kind of thing about in books and on line.

Instead, let’s look at what it means to migrate from a static, an instance or a singleton over to using a DI container, specifically OpenNETCF’s IoC framework.

First, let’s look at a “service” class that exposes a single integer and how we might consume it.

   1: class MyStaticService
   2: {
   3:     public static int MyValue = 1;
   4: }

And how we’d get a value from it:

   1: var staticValue = MyStaticService.MyValue;

Simple enough.  Some of the down sides here are:

  • There’s no way to protect the Field value from unwanted changes
  • To use the value, I have to have a reference to the assembly containing the class
  • It’s really hard to mock and cannot be moved into an interface

Now let’s move that from a static to an instance Field in a constructed class:

   1: class MyInstanceService
   2: {
   3:     public MyInstanceService()
   4:     {
   5:         MyValue = 1;
   6:     }
   7:  
   8:     public int MyValue { get; set; }
   9: }

Now we have to create the class instance and later retrieve the value.

   1: var service = new MyInstanceService();
   2:  
   3: // and at a later point....
   4: var instanceValue = service.MyValue;

We’ve got some benefit from doing this.  We can now control access to the underlying value, making the setter protected or private, and we’re able to do bounds checking, etc.  All good things.  Still, there are downsides:

  • I have to keep track of the instance I created, passing it between consumers or maintaining a reachable reference
  • I have no protection from multiple copies being created
  • The consumer must have a reference to the assembly containing the class (making run-time plug-ins very hard)

Well let’s see what a Singleton pattern buys us:

   1: class MySingletonService
   2: {
   3:     private static MySingletonService m_instance;
   4:  
   5:     private MySingletonService()
   6:     {
   7:         MyValue = 1;
   8:     }
   9:  
  10:     public static MySingletonService Instance
  11:     {
  12:         get
  13:         {
  14:             if (m_instance == null)
  15:             {
  16:                 m_instance = new MySingletonService();
  17:             }
  18:             return m_instance;
  19:         }
  20:     }
  21:  
  22:     public int MyValue { get; set; }
  23: }

And now the consumer code:

   1: var singleTonValue = MySingletonService.Instance.MyValue;

That looks nice from a consumer perspective.  Very clean.  I’m not overly thrilled about having the Instance accessor property, but it’s not all that painful.  Still, there are drawbacks:

  • The consumer must have a reference to the assembly containing the class (making run-time plug-ins very hard)
  • If I want to mock this or swap implementations, I’ll got to go all over my code base replacing the calls to the new instance (or implement a factory).

How would all of this look with a DI container?

   1: interface IService
   2: {
   3:     int MyValue { get; }
   4: }
   5:  
   6: class MyDIService : IService
   7: {
   8:     public MyDIService()
   9:     {
  10:         MyValue = 1;
  11:     }
  12:  
  13:     public int MyValue { get; set; }
  14: }

Note that the class is interface-based and we register the instance with the DI container by *interface* type.  This allows us to pull it back out of the container later by that interface type.  The consumer doesn’t need to know anything about the actual implementation.

   1: // Note that the Services collection holds (conceptually) singletons.  Only one instance per registered type is allowed.
   2: // If you need multiple instances, use the Items collection, which requires a unique identifier string key for each instance
   3: RootWorkItem.Services.AddNew<MyDIService, IService>();
   4:  
   5: // and at a later point....
   6: var diValue = RootWorkItem.Services.Get<IService>().MyValue;

Mocks, implementation changes based on environment (like different hardware) and testing become very easy.  Plug-in and run-time feature additions based on configuration or license level also are simplified.

Monday, September 17, 2012 1:07:54 PM (Central Daylight Time, UTC-05:00)  #     | 
# Wednesday, August 29, 2012

I’ve just checked in new code changes and rolled a full release for the OpenNETCF ORM.  The latest code changes add transaction support.  This new release adds a load of features since the last (the last was way back in February), most notably full support for SQLite on all of the following platforms: Windows Desktop, Windows CE, Windows Phone and Mono for Android.

Wednesday, August 29, 2012 12:12:37 PM (Central Daylight Time, UTC-05:00)  #     | 
# Tuesday, August 23, 2011

We've been heavily dogfooding the IoC project (and others) lately and I finally took the time today to back-port the fixes and updates to the public code. This is being used for a solution that runs on both the desktop and the compact framework, so it's been heavily tested under both of those environments. The new release (1.0.11235) is now available on Codeplex.

Tuesday, August 23, 2011 1:23:26 PM (Central Daylight Time, UTC-05:00)  #     | 

Like most people, the more projects I work on the more I find myself reusing common bits and pieces of code. For the past year or so I've been collecting these pieces into a library I called OpenNETCF.Extensions.  The name was becasue they originally started as a set of extension methods that helped me to compile one code base for Windows Phone, the Compact Framework and the full framework, but it eventually started expanding in scope.  I added a fairly robust set of method for validation, a set of classes for helpiing make REST clients, a class for a circular buffer (FIFO) and generally anything I found myself using on multiple projects.

Since many of those projects are already open-source, it started becoming a pain maintaining a single, controlled source for these helpers.  So in an attempt to centralize it, I've created yet one more open source project.  My plan now is to have all of the consuming projects only use binary releases from this project.

So, with that said, go ahead and check out the new MIT-licensed OpenNETCF Extensions project over on Codeplex.

Tuesday, August 23, 2011 12:52:23 PM (Central Daylight Time, UTC-05:00)  #     | 
# Thursday, March 10, 2011

I've published a major upgrade to the OpenNETCF MTConnect Managed SDK over on Codeplex.  Earlier releases only had Agent support, but this release adds Client support.  The SDK supports both the Compact Framework and the Full Framework (version 3.5 of each).

If you're wondering exactly what MTConnect is, it is a standard for how data should be published from machine tools as XML over a simple Web interface.  More information on the standard can be found on the MTConnect Institute's web site, including the full specification.  This SDK allows managed developers to publish and/or consume data according to the standard.

Thursday, March 10, 2011 12:11:23 PM (Central Standard Time, UTC-06:00)  #     | 
# Thursday, December 09, 2010

The MTConnect Agent SDK I published last week is really only useful if you implement a Host to actually serve up the data.  The IHost interface isn't complex, but if you don't have an example, it's a bit difficult to understand my intent.  I've published a desktop implementation that uses Padarn as the web server.  In theory the same code should work under Windows CE as well, but I've not yet tested it to be certain.

Thursday, December 09, 2010 11:30:59 AM (Central Standard Time, UTC-06:00)  #     | 
# Thursday, December 02, 2010

I do quite a bit of my work in the area of industrial automation, and one of the more interesting initiatives to come along in a while is called MTConnect ("MT" presumably for "Machine Tool").  MTConnect is an open standard for communicating with a machine tool to retrieve information about its current or past status - everything from executing controller line of code to tool head positions.  It's interesting enough that I joined the Technical Advisory Group and am helping to review and improve the specification (version 1.1.0 was just ratified last week).

As frequently seems to be the case, there was a bit of interest from other members on exposing MTConnect data from tools running Windows OSes (both CE and XPe), but no one working on providing an actual SDK to allow a standardized way to actually do it.  Well implementing code from nothing but a spec is actually something I find pretty fun and interesting, so I took up the challenge.  My first attempt was, as is typical, more of a throw-away attempt at writing code to help me understand how the spec itself works.  I spent a couple weeks on it then tossed it all out.

I then took the knowledge I gained from that first effort and put together a more coherent SDK that I'm releasing a loose Beta of today over on Codeplex.  It's not done - in fact I wanted to get a few more features in and get it to a releasable point before publishing it, but I've already gotten inquiries and volunteers to test out the beta work, so I'm publishing early to facilitate sharing the code between teams and to allow me to track bugs and discuss the SDK in a publicly searchable location.

I'm working on a specific project that is going to use this SDK, so I have a specific set of funtionality that I'm driving toward, but that doesn't mean I'm not open to making it easier for everyone to use. If you're working on machine tool controllers and are interested in exposing data meeting the MTConnect standard, I encourage you to take a look at the Agent SDK, post questions in the Discussions area and report bugs/desired features to help drive the effort forward.

Thursday, December 02, 2010 4:16:34 PM (Central Standard Time, UTC-06:00)  #     | 
# Thursday, May 06, 2010

We recently ported a desktop SCSF/CAB application over to use the OpenNETCF.IoC framework.  The primary thinking here was that the SCSF has way, way more stuff than we really need, want or use and the SCSF wizards had done wacky things to a few Studio installations, so we wanted to get rid of all of that as well.

I've checked in the fruits of the labors into the Codeplex project, including new desktop project and solution files.

Now you can be even closer to one codebase for both desktop and device projects.  If nothing else, it allows you to not have to remember two different injection frameworks if, like me, you end up doing a lot of work on both platforms.

Thursday, May 06, 2010 5:48:28 PM (Central Daylight Time, UTC-05:00)  #     | 
# Friday, June 26, 2009

As you may have guessed from some of my recent blog entries, we're making a push to get a lot of our shared source code out to the Codeplex servers.  Our serial library is the latest one to make the move.  It's now available at http://serial.codeplex.com.  As with all of these libraries, if you have the desire to contribute, fix, extend, or whatever just let us know and we'll add you as a developer.

Friday, June 26, 2009 9:24:33 AM (Central Daylight Time, UTC-05:00)  #     | 
# Thursday, June 25, 2009

In an effort to clean up our servers, to make code easier to find, and to hopefully make it easier for the community at-large to contribute, we've moved our popular Desktop Communication library over to the Codeplex servers.

Visit the project at rapi.codeplex.com.

Thursday, June 25, 2009 6:38:36 PM (Central Daylight Time, UTC-05:00)  #     | 
# Thursday, January 03, 2008
As it seems is always the case, as soon as I published the WIA library, I found some problems.  The original library worked fine in the test application, but as soon as I moved it into a larger-scale application that does a lot of wacky multi-threading, multi-AppDomain and reflection calls I started to see bad behavior.  It all worked fine if you kept the original list of cameras, but if you added or removed them they started shifting around or existing cameras no longer worked.  So I've debugged and reworked it a bit and the new version appears to be much more stable and friendly in a production environment. 

Download the code at the original blog entry.

Thursday, January 03, 2008 4:35:38 PM (Central Standard Time, UTC-06:00)  #     | 
# Monday, December 31, 2007
Last Christmas (2006) I gave my father a USB turntable so he could start ripping his hundreds upon hundreds of vinyl albums to MP3.  Of course I assumed that all was going well for most of the year, as he was using it and seemed happy with it. 

Then about 2 months ago I actually got a copy of the Simon and Garfunkel song Cecilia from him (don’t tell the RIAA) and I noticed that it didn’t show up in my Zune software or in WMP.  A little further digging and I found it down in “unknown artist, unknown album, unknown song”.  How wonderfully useful.  So I asked him why the hell it didn’t have the track info.  He replied that the software he has basically ripped the vinyl to one giant wave file, then another piece of software would divide it into MP3 tracks, but it didn’t have a good way of tagging each track efficiently.  To give it track info, he’d have to pull it into some other software like WMP and alter it there, which is a very tedious process.

Well I decided to take a look into how media playback software actually got the info about the tracks.  I assumed it was something embedded in the software so I did a little searching for a specification, and found that the info is indeed stored in what is called an ID3 header tag.  Well since I enjoy writing software from nothing but a spec (really, I do – masochistic I know) I decided that maybe I’d put together some software that makes tagging albums just a bit easier using mostly drag and drop and inferring info based on how it’s organized in the file system.

The first step, however was to create a library that allowed me to read and write the ID3 tags.  That yielded the OpenNETCF.Media.MP3 library (this library does *not* offer MP3 playback capabilities, so don’t ask).

Once I had the library mostly done (meaning coded but not heavily tested) I then started on a desktop application I called AudioTagR.  The idea behind AudioTagR is that most people organize their music on their file system.  My dad and I both have a single folder that contains a folder for each artist.  Each artist folder contains one or more folders for each album.  Each album folder contains files that are the MP3 songs, and the song filenames are in the format “NN <song name>.mp3” where NN is the track number from the album.  AudioTagR assumes that you use this hierarchy to infer a lot of the information about unknown tracks (though it allows you to turn off inferring).

So the paradigm is that on the right is a folder view of the file system, with a root being the “root” of where your music is stored.  On the left is an “organizer” that is used for nothing but tagging tracks through inference.  You drag a song from the file tree into the organizer tree and it infers artist, album, song name and track if nothing exists.  If some info exists, or you drop it onto a node in the ordanizer that already exists, it will use node info instead of inferring.  The actual algorithm is a little more complex than I feel like explaining, but it all makes logical sense when you use it, so if you really want to know how it works, try it out.


So the day before Christmas I delivered v1 to him, and less than 2 minutes later he found the first bug.  After a couple versions of deploying via FTP, I decided there had to be a better mechanism.  Since this is a desktop app (yes, sometimes I begrudgingly work on non-CE stuff – but hey, the ID3 tag library is fully CF-compatible) I decided I’d see what the whole ClickOnce deployment and publishing stuff was about.  Sure enough, it turned out to be crazy simple, so I set up a publication that allows installation from a web page and now the software auto-updates on his machine every time I make a fix.

So now  that it’s done, I guess that there may be other people out there that received these nice USB turntables and are having a similar problem, so I say Merry Christmas to you all.  I’m giving away AudioTagR, along with the full source if you want it, to everyone as another OpenNETCF shared source project (MIT X11 license).  Since it is free, you get no support, and I take no responsibility for its use or consequences.  If you screw up the titles on all of your existing music I’m sorry but it’s not my fault.  Make a backup.  If you find a bug, by all means let me know and I’ll see what I can do to fix it.  If you add a feature that you like, send me the code and I can integrate it in.
 

If you simply want to install and use AudioTagR, click here.

Download the full source (C#) here
Get the OpenNETCF.Media.MP# library source here

Monday, December 31, 2007 2:41:33 PM (Central Standard Time, UTC-06:00)  #     | 
Before I go any further, let me state for the record that this library does not provide any ability to play MP3 files, so if that's what you were thinking from the name, then don't get too excited.

The OpenNETCF.Media.MP3 library is a library that allows you to read and write ID3 tags to MP3 files.  It's both Compact Framework 2.0 and Full Framework 2.0 compliant.  For a usage sample, see the AudioTagR project.

The general object model looks like this:



It's licensed under our very open MIT X11 license.
Download the full source code (C#) here.

Monday, December 31, 2007 2:25:40 PM (Central Standard Time, UTC-06:00)  #     | 
# Friday, December 21, 2007
For the last couple weeks I've been struggling with getting camera capture inside a desktop application (yes - I lower myself to do desktop development occasionally).  The problem I'm finding is that API documentation and especially sample availability for things like DShow and Windows Image Acquisition (WIA) are pretty poor and there seem to be no reasonable, comprehensize samples on how to use any of it.  Occasionally you find something on sites like CodeProject, but IMO those projects tend to suck.  The authors typically "solve" a specific problem by writing code tightly coupled to the problem they're solving, so the code is very rarely reusable or extensible, and the quality usually is lacking as well.

Well today I finished up a general library and test harness for WIA.  It's too soon to tell if we'll actually use it in the application I'm working on, since it's missing a lot of capabilities that DShow will likely be better for, but to save a little headache in the developer community, I'm making it shared source (under our typical MIT x11 license).  It provides a simple object model for seeing what cameras you have, displaying live video from them and grabbing frames.  The test harness generates a TabControl with a page for each camera you have plugged in.  If you add or remove a camera while the app is running, tabs are added or removed.

Most importantly I designed the clas library for general use.  It can be dropped into any project and consumed for camera control without a bunch of rewrite, and while I'm not going to say it's bug free, I at least tested it though several scenarios and let it run for a fairly long time without it puking (which is more than I can say about pretty much anything else I found).

Below is the object model and a screen shot of the test app.





Download the source code here (Updated 1/3/08).
Friday, December 21, 2007 3:14:58 PM (Central Standard Time, UTC-06:00)  #     |