Dismissile Dismissile - 1 year ago 87
C# Question

Multiple platform projects and NuGet

I have created a library that I need to be able to use in a Portable Class Library as well as a regular .NET application. The way I accomplished this is by creating multiple solutions / projects that point to the same files:


Dismissile.sln includes Dismissile.csproj and targets .NET Framework 4.5.2
Dismissile.Portable.sln includes Dismissile.Portable.csproj and is a portable class library project that targets .NET Framework 4.5, Xamarin.Android and Xamarin.iOS.

Each project includes Class1.cs. I have created some conditional compilation symbols in each project such as PORTABLE and NET452.

This seems to work so fine but now I need to add a NuGet package for JSON.NET into my projects.

If I add a NuGet package in my Portable project it will create the following in my packages.config:

<package id="Newtonsoft.Json" version="9.0.1" targetFramework="portable40-net40+sl5+win8+wp8+wpa81" />

However, if I add it in my other project it will create the following in packages.config:

<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net40" />

Is there any way to have a separate packages.config so each project includes the correct reference to my NuGet dependencies?

Answer Source

The easiest solution for this scenario is to create distinct folders for every project and include the .cs-files via a link. (see MSDN - Add as Link)

Doing so enables you to reference different packages (and versions) for different platforms (projects), as you have distinct packages.config-files.

Additionally, I should mention that you may encounter incompatible framework methods (such as Task.Factory.StartNew for NET40 and Task.Run for NET45), which can be solved in two different ways:

Working with compiler constants

Define a framework contstant in your projects, and query them with preprocessor-directives, like:

#if NET40
#elif NET45

Working with partial classes and methods


public partial class Foo
  public void Bar()
    // ...

  partial void RunTask(Task task);


public partial class Foo
  partial RunTask(Task task)


public partial class Foo
  partial RunTask(Task task)


My preferred solution is partial classes and methods, as they don't mess up your source with nestings (due to #if-statements), stepping while debugging is way more natural, and finally this approach is more flexible for complicated scenarios.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download