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.
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.
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.
I’ve pushed another ode update for the OpenNETCF IoC Framework into Codeplex. Highlights in this one are the fact that I’ve added a WorkItems collection to the WorkItem class, meaning there’s now the potential for parent/child relationships.
I’ve been using the OpenNETCF IoC framework for several new projects lately, and I really like it. I think my favorite feature is the fact it gives you the ability to subscribe to events from other objects without requiring an instance of the event publisher. In fact you don’t even need to know the publishers type or even of its existence – you simply need to know the name of the event that might get raised.
The only downside I’ve hit lately is that the performance for creating objects is not fantastic. Of course that’s to be expected. To achieve all of this really loosely coupled architecture, we have to rely heavily on Reflection. Not only do we have to do object creation through Reflection, but we have to do a lot of complex querying looking for type names and attributes, and this can take a while.
In an effort to improve things a bit, I’m working on updating the internal ObjectFactory class that is responsible for all of this heavy lifting. I’ve added caches for most of the items that get queried through Reflection. For example now when we want to find all of the published events from a specific Type, we use reflection the first time, but every subsequent time we pull the list from a cache.
A unit test for creating a single object that both publishes and subscribes to events yields nearly a 5,000% improvement in creating speed for the second object of the same type. Yes, you read that right – it is 50 times faster creating the exact same object type the second time around. There’s no avoiding the pain the first time we have to inspect a Type, but I’ve already noticed a marked improvement in app startup time using the new changes.
It took a long time to get here, but we’ve finally release what I’m calling the version 1.0 (pervious version were 0.9.x) release of the OpenNETCF.IoC Framework. In case you’ve not been tracking this project, it is a public-domain-licensed (you can’t get any more free and unencumbered than that) framework that provides both inversion of control and dependency injection for .NET Compact Framework applications (it can be used on the desktop as well). It’s roughly modelled after Microsoft’s SCSF and CAB frameworks, but it’s scaled down and optimized for running on mobile and embedded devices, plus I “fixed” stuff that I think the SCSF got wrong (like having a static, globally available RootWorkItem and the ability to insert IMessageFilters into the application’s message pump).
This framework is in use in a couple of commercial applications already, so it’s been pretty heavily tested and vetted. I still want to add a few more features as well and go back through it looking for performance optimizations, but it certainly has enough features to be used in applications today.
This release also ships with a full-blown, real-world sample application, not just the typical “Northwind” type of application. The sample is called WiFiSurvey and it can be used to survey WiFi AP coverage of a site and to monitor associated AP changes as well as network addressability of a device.
WiFiSurvey has a Configuration service, a SQL CE 3.5-backed Data Access Layer, an Infrastructure module and a an application shell all of which are fully decoupled from one another and that are all loaded dynamically using an XML definition file. The shell makes use of both a DeckWorkspace and a TabWorkspace, showing you not just how to use them, but also how to create your own workspaces if need be.
The WiFiSurvey application has a single source base for all target platforms and has been tested on the following platforms:
- ARM-based CE 6.0 with a 320×240 (landscape) display.
- Pocket PC 2003 240×320 (portrait)
- WinMo 5.0 240×320 (portrait and landscape)
The IoC framework has additionally been tested on x86-based CE 5.0 and CE 6.0 devices.
As a side note, the WiFiSurvey sample application is also a good example of using the OpenNETCF Smart Device Framework for getting wireless information.
I’ve released yet another version of the OpenNETCF.IoC Framework. This release has a few minor fixes over what I shipped last week, but more important is that it includes the start for a more complete example. The new sample shows how to dynamically load modules based on a configuration XML document and how to use the DeckWorkspace.
If you’re using the framework, please let me know. I see that it’s been downloaded and we’re getting some questions and bug reports, so I know that people are at least testing it out, but I’ve gotten no feedback as to whether anyone finds it useful of not.