0
votes

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:

Src/
    Dismissile.sln
    Dismissile.Portable.sln
    Dismissile/
        Dismissile.csproj
        Dismissile.Portable.csproj
        Class1.cs

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?

1

1 Answers

1
votes

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
Task.Factory.StartNew(...)
#elif NET45
Task.Run(...)
#endif

Working with partial classes and methods

Dismissile.NET40\FooClass.cs

public partial class Foo
{
  public void Bar()
  {
    // ...
    this.RunTask(task);
  }

  partial void RunTask(Task task);
}

Dismissile.NET40\Partial.FooClass.cs

public partial class Foo
{
  partial RunTask(Task task)
  {
    Task.Factory.StartNew(task);
  }
}

Dismissile.NET45\Partial.FooClass.cs

public partial class Foo
{
  partial RunTask(Task task)
  {
    Task.Run(task);
  }
}

Summary

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.