Share Code (#if FULL_FRAME)

Fri, September 17, 2004, 11:00 AM under MobileAndEmbedded
When talking about .NET code running on both CE platforms (against CF) and the PC (full FX), usually what follows is a discussion on sharing the same binaries. This is possible and we looked at retargetable previously. My prefered approach is to share code instead. Two projects, two outputs, same set of code files. Before talking about the advantages of this approach, let's briefly summarise the process.

Basically we create two projects, one for the full FX and one for the CF. In the full FX project we add a conditional compilation constant; I name it FULL_FRAME, but obviously it can be whatever you fancy. Then we share the same code files between the two projects. This can be done by creating the file in one project and then adding a link to it from the other or even better, place the projects in the same directory and include the code files in both projects. Either way you are working on the same file, not a copy. I rename the output of the CF assembly by appending a CF to it before the extension, but obviously the namespaces etc inside are the same. Build both projects and you get two outputs (make sure one does not overwrite the other). Now, whenever you need to add some desktop-only functionality, you just surround the code with FULL_FRAME e.g.

using System.Threading;

Thread t = new Thread(new ThreadStart(this.SomeMethod));
t.Name = "CF2.0 supports both of these";
t.IsBackground = true;

If any of the above is unclear, drop me a comment (it is also described here). I maintain a fairly large set of dlls between the two platforms (the desktop side uses remoting and COM interop which are non-existent on the CF) and it works great.

The advantages of this approach are obvious. You can enhance the desktop assembly with full FX specific features and vice-versa for the CF assembly. In fact, even when there is no business case for it, I do this for every CF dll I write. By running your CF code on the desktop you can debug using features not available when debugging on the device/emulator, such as "Set Next Statement" and full tracing support; there are a whole bunch of profilers (none for CF) you can use, e.g. for examining allocation patterns of your code; modelling tools that don't work with CF projects can be used to design or reverse engineer your code; same goes for unit testing tools and so on and so forth: I hope you get the point. Through simple, short tasks you can get great benefits and it amazes me how very few devs use this technique.

When discussing retargetable, I offered my opinion on why it didn't make sense for EXEs. With the shared code approach I create an EXE project per platform, but no code sharing takes place; they just reference the corresponding dlls. This is one of the reasons I make my EXE assemblies very thin, typically containing only Forms. The difficulty is that the forms designer is very different between the two project types (in terms of auto generated code). Trying to share the form code would effectively mean not using the designer at all. However, with VS2005 and partial classes the story might get better. I'll be looking at having different designer code files while sharing the partial form class which contains the event handlers and other methods. You can imagine how the form can be designed (and properties of its controls set) in such a way as to fit in both platforms, while the real logic is the same. Too excited about this now, I must go play with it!