# Tuesday, October 13, 2009

Recently I got feedback from Nick Randolph, another device developer MVP, regarding the OpenNETCF.IoC framework and handling the lifecycle of IDisposable objects (well we taked about a few things, but this is the one I tackled first).  The problem is that if you add an IDisposable object to any DI container (be it OpenNETCF.IoC, Unity, Ninject or whatever) the container knows nothing about the object's Disposed state.  Unfortunately the IDisposable interface doesn't expose an IsDisposed property or OnDisposed event. 

SO what, exactly, is the problem?  Well, let's assume we create an IDisposable object and add it to the DI container.  AT some point later, we're done with the object, so we call Dispose.  Well that internally releases the object's native resources, but the object itself still has a root (the reference from the container) and so the GC will never actully collect the object and its managed resources.  On an embedded device this could be a problem.

The solution that we came up with is to create a wrapper for IDisposable objects and a new set of methods for the container for adding.  So now you can do something like this:

var instance = RootWorkItem.Items.AddNewDisposable<MyDisposableType>();

Now instead of this returning an instance of MyDisposableType, it returns a container object that holds it.  You access the MyDisposableType object itself via the Instance property of the container, which requires some small code work on the consumer's part, but the nice thing is that when you call Dispose on that container, it in turn calls Dispose on the contained instance *and* it removes the object from the DI container so the GC can do it's work on the object.

I've not rolled a new framework release with these changes because they really are just a proposed solution for now.  If you're interested, go ahead and pull the latest code from the source code page (change set 32718) on the project site and give it a try.  There are a load of new unit tests that show the general idea on usage.

Tuesday, October 13, 2009 3:51:31 PM (Central Daylight Time, UTC-05:00)  #     | 
# Friday, October 09, 2009

Today I got a question from a customer, that essentially was "how can I detect when the network cable has been plugged in or unplugged from my CF application."  I knew I has solved this before, and after a little bit of digging with search engines I was reminded how obscrure finding the answer to this, even from native code, is.

So the general answer for how this is detected is that you have to call down into the NDIS driver via an IOCTL and tell it that you're interested in notifications.  This is done with the IOCTL_NDISUIO_REQUEST_NOTIFICATION value.  Of course receiving the notifications isn't so straightforward - you son't just get some nice callback.  Instead you have to spin up a point to point message queue and send that in to the IOCTL call, along with a mask of which specific notifications you want.  Then, when something changes (like the cable is pulled) you'll get an NDISUIO_DEVICE_NOTIFICATION structure on the queue, which you can then parse to find the adapter that had the event and what the exact event is.

From a managed code perspective, this is actually a lot of code to have to write - CreateFile to open NDIS, all of the queueing APIs, the structures for the notifications, etc.  Fortunately, I'd already been down this road and had added it to the Smart Device Framework already.  So if you're using the SDF, getting the notifications looks like this:

public partial class TestForm : Form
{
  public TestForm()
  {
    InitializeComponent();

    this.Disposed += new EventHandler(TestForm_Disposed);

    AdapterStatusMonitor.NDISMonitor.AdapterNotification += new AdapterNotificationEventHandler(NDISMonitor_AdapterNotification);
    AdapterStatusMonitor.NDISMonitor.StartStatusMonitoring();
  }

  void TestForm_Disposed(object sender, EventArgs e)
  {
    AdapterStatusMonitor.NDISMonitor.StopStatusMonitoring();
  }

  void NDISMonitor_AdapterNotification(object sender, AdapterNotificationArgs e)
  {
    string @event = string.Empty;

    switch (e.NotificationType)
    {
      case NdisNotificationType.NdisMediaConnect:
        @event = "Media Connected";
      break;
      case NdisNotificationType.NdisMediaDisconnect:
        @event = "Media Disconnected";
      break;
      case NdisNotificationType.NdisResetStart:
        @event = "Resetting";
      break;
      case NdisNotificationType.NdisResetEnd:
        @event = "Done resetting";
      break;
      case NdisNotificationType.NdisUnbind:
        @event = "Unbind";
      break;
      case NdisNotificationType.NdisBind:
        @event = "Bind";
      break;
      default:
        return;
    }

    if (this.InvokeRequired)
    {
      this.Invoke(new EventHandler(delegate
      {
        eventList.Items.Add(string.Format("Adapter '{0}' {1}", e.AdapterName, @event));
      }));
    }
    else
    {
      eventList.Items.Add(string.Format("Adapter '{0}' {1}", e.AdapterName, @event));
    }
  }
}

 

Friday, October 09, 2009 10:08:32 AM (Central Daylight Time, UTC-05:00)  #     | 
# Wednesday, October 07, 2009

It's been a while since I did any check-ins to the OpenNETCF.IoC framework.  It's not due to lack of interest or lack of thought on my part.  I've just been very, very busy lately.  We've now using the IoC project in a few commercial applications with very good results, so there isn't a whole lot more to add (though I do want to add some sort of lifecycle management capabilities).

In the hope of getting a little more adoption of the framework, I've added an adapter to OpenNETCF.IoC for the Microsoft Patterns and Practices CommonServiceLocator (CSL).  You can use CSL code to extract object instances from the Items collection.  My hope is that this makes it easier for development teams using CSL to integrate OpenNETCF.IoC into their mobile and embedded projects.

If you have any other ideas or feature requests for OpenNETCF.IoC, by all means submit a request or start a discussion on the project site.  And if you're using it, I'm always interested to see how it's working out.

Wednesday, October 07, 2009 1:13:45 PM (Central Daylight Time, UTC-05:00)  #     | 
# Tuesday, October 06, 2009

When you hire a consultant you're not simply getting someone to sling code (if that's what you want, hire a contractor).  Sure we do that, but we bring along a lot of experience, and quite often a plethora of code libraries.  We tend to see a wide variety of applications and tend to build up wide repositories of knowledge.  For example we're just putting finishing touches on a C# wrapper for using the Anviz SM2000 fingerprint reader.  It's a low-cost OEM module that seems to perform pretty well.  So if you're building a custom Windows CE (now Windows Embedded Compact to be true to Microsoft's marketing engine) device where you need fingerprint authentication, we could have you enrolling and authenticating fingerprints from a managed application very, very quickly instead of you spending a week or more trying to build up code from a not-so-clear spec document.

Tuesday, October 06, 2009 9:34:25 AM (Central Daylight Time, UTC-05:00)  #     | 
# Friday, October 02, 2009

Very often we here at OpenNETCF work on projects that are internal to companies that is seen by relatively few people or we do infrastructure work that helps an app succeed, but it isn't the app itself. Sometimes, though, we do get an opportunity to write public, commercial applications.  We've just finished version 1 of Trapster for Windows Mobile, which chould hit the Windows Marketplace this month.  For more info on what Trapster is and how it works visit their website, or read one of their reviews such as that on PocketNow or CNET.

The pieces of note here are that we used the OpenNETCF IoC Framework for dependency injection and the Bing Maps web services for all of the mapping and navigation work.

Friday, October 02, 2009 7:58:57 AM (Central Daylight Time, UTC-05:00)  #     |