Using Shared Projects with NETMF

VS2015 is out and free to use and (excepting for the moment, Gadgeteer) supports NETMF and one of the neater features to come along in a while is “Shared Projects”. I use these all the time for sharing code between platforms (especially useful with Xamarin).

When you reference a shared source project from another ‘normal’ project (class library or program) then all of the files in the shared project get compiled into your class-library or program. That is, they get included as source code as if they were part of the project you are compiling. This is a much easier approach than the previous practice of using symbolic links to include source files in more than one project, because when you add a file to a shared source program, it is automatically linked into all the projects that reference that shared source project.

The problem is, currently you can’t use “Add Reference” to add a shared source project into a NETMF project. However, you can still make this work for NETMF.

To reference a shared source project, right click on the project and select “Unload project” and then “Edit project”. Go to the end of the .csproj file and in front of the first <Import…/> line, add this:

Now, of course, the path has to point to your shared-source project file, so make sure the path is correct (it should be a relative path, relative to the location of your .csproj file) and the file name should be the name of your shared source project file with .shproj changed to ".projitems".

When you complete the edit, hit Ctrl-S and the right click on the project again and select "Reload project"

You should now see something like the screen capture below (note that Verdant.Vines.XBee.Shared is included in the NETMF and UWP projects.  So now you can write source code for both UWP and NETMF or for multiple different NETMF platforms at the same time and at the source-code level (remembering the restrictions on NETMF syntax of course - you must code to the least common denominator).  If you need platform-specific code (you will) then place that in either the UWP or NETMF project and it will only get compiled there.

@ mcalsyn - Nice! This helps solve the problem of breaking NETMF development down into many “component” projects yet keeping the size down by compiling to a single assembly. :slight_smile:

@ ianlee74 - Good point - yes, it does indeed

@ mcalsyn - Thank you.

I would welcome some “best practices” or “your practices” on setting up netmf projects and their associated helper classes/projects. What do you put in your main class and what do you push out to other classes etc.

It’s really hard to answer broad questions because the answer always turns out to be “it depends”.

But here are some general rules of thumb that I follow - and I definitely offer them up as “my practices” and make no claim of possessing any “best practices”. Not all of them have to do with how you write code.

I am a big believer in inversion-of-control and dependency inversion frameworks. I use Ninject in almost every desktop, mobile, and cloud asset that I build, and I have used a home-grown version of TinyIoC in my netmf code. You can find examples in the Radius project, and no doubt Ninject and TinyIoC will find their way into multiple parts of Verdant.

Build mocks and unit test code as you work - not after. And sometimes, I have dabbled in test-driven development (building the interfaces, mocks and test code first, and then filling in functionality). Use the IoC/DI frameworks as a way to bring in mocks during testing.

MVVM is my model of choice for all of the UI work I do (desktop, moble, and web). I can’t make the same claim for netmf because I haven’t done anything more than trivial debug output there - though that is bound to change. Not sure how practical it is to expect to have room for mvvm on netmf.

Design for reuse. Use shared source projects and portable class libs. I do (or did until the netmf addiction set in) a lot of mobile development, and your return on labor investment will be directly related to your ability to componetize, abstract, and reuse your past efforts over time and across platforms. Xamarin is a great tool for extending your reach and reuse, and .net is development lubricant - you get more functionality with greater reach achieved faster.

Architect broadly/strategically; but implement tactically. Write code for rapid results (or a quick failure). But know where you are going - have a big picture plan, but then pick a useful smaller piece to finish. This can also be interpreted as building for the Minimally Viable Product (MVP). Code talks - everything else walks.

Agile methodologies work - even for individual ISVs. Set a goal - it can be hours long, days long, or a couple weeks long, but keep it small enough that you can get your head around it. Constantly watch for mission creep in that sprint. If yaks need shaving, make them a sprint. Maintain a backlog on Visual Studio Online or sticky notes or something. I can’t tell you how many times I have gotten lost on my way somewhere, and agile discipline is the little angel on your shoulder that can keep you true to your goal.

Think like an academic, but code for maintenance. That is, know the execution cost (big-O notation - cost of execution as a function of input size) and memory cost of the code you are writing, but then write your code with clarity because someday, you will have to read this code again.

Don’t debug comments. They lie.

Share and share alike. Every successful independent dev that I know is an active and giving member of a coding community.

1 Like

It’s like adding shared files, like we used to do in many previous versions, but a whole project at a time. Neat!

1 Like

@ mcalsyn - Thanks for posting this I’ve seen mention of this but not looked and had no idea it was was you describe it, very interesting. I’ve got a large solution (UPnP library) that is three class library projects (Phone, Desktop and Store) each referencing a common source folder (with conditional compilation symbols for platform specific code) it will be interesting to see how this new sharing mechanism can help out here.