Using project.json for other project types

If you use VS2015 to create a new UWP project, there are three interesting things in the References node:

  1. Analyzers - this node lets you use so-called "Roslyn analyzers", which allows anyone to add extra warnings and error messages and quick-fixes into the IDE. Read more about it here: https://msdn.microsoft.com/en-us/magazine/dn879356.aspx
  2. project.json - this is used by UWP projects instead of "packages.config" to manage the NuGet packages you've installed. It brings many advantages. Read about them here: https://blog.nuget.org/20150729/Introducing-nuget-uwp.html
  3. Microsoft.NETCore.UniversalWindowsPlatform - in UWP apps, even the .NET framework and runtime themselves are delivered via this NuGet package.

 

Folks have asked: "Can I get the benefits of project.json in my other (non-UWP) projects? " The answer is technically yes, but this area isn't finished yet. But it's interesting to learn about it.

NOTE: For all of this, you need to have the Win10 Tools installed into VS. That's because project.json was introduced into VS in order to support Win10 development. Instructions on how to add the Win10 tools are here.

NOTE: Everything in this post is "unsupported". That doesn't mean "impossible". What it means is that it wasn't one of the scenarios that was forefront in mind while the feature was being developed, and it hasn't been tested in all kinds of scenarios you'll want to use it, and there are probably pieces missing.

A .NET46 console app using project.json

(1) Do File > New > Project > VB > Windows > ClassicDesktop > Console Application, and choose ".NET 4.6" in the dropdown at the top of the new-project dialog.

(2) Next, add a new file "project.json" to your project, with this content:

 {
  "dependencies": {
    "Newtonsoft.Json": "7.0.1"
  },
  "frameworks": {
    "net46": { }
  },
  "runtimes": {
    "win": { }
  }
}

(3) Next, unload+reload your project and rebuild.

You'll observe a number of things:

  • The References node shows Newtonsoft.Json as a NuGet reference. That indicates that it's being picked up via project.json, not via the traditional packages.config way.
  • One of the nice things about project.json is that to add a new package, it's enough merely to edit the project.json file and add a dependency. You don't need to go via the Manage NuGet Packages > Install dialog, nor the NuGet console.
  • The .NET runtime+framework are not delivered via NuGet in this console app. That only happens in UWP and ASP.NET 5 projects.

 

A class library using project.json

If you create a new Portable Class Library that targets .NET4.6, Windows10 and ASP.NET 5, or a subset of them, then it will use project.json by default.

But what to do if you want to gain the benefits of project.json, and yet still need your PortableClassLibrary to target .NET4.5?

One approach is to create an ASP.NET 5 class library project (also called xproj). This uses project.json by default.

Another approach is to create a Portable Class Library, and then add in the project.json file manually, similar to how we did with the console app. As I said, project.json isn't finished yet. Here's what you can do, and how to work around the "not finished yet" part...

 

(1) File > New > Project > VB > Windows > Classic Desktop > either a normal ClassLibrary targeting .NET4.5, or a Portable Class Library targeting whatever you want.

(2) Add this project.json file, unload then reload, then build. This will make your class library now use project.json instead of packages.config:

{
  "dependencies": {
    "Newtonsoft.Json": "7.0.1"
  },
  "frameworks": {
    "net45": { }
  },
  "runtimes": {
    "win-anycpu": { }
  }
}

(3) Now create a .NET45 application, e.g. a ConsoleApp. And add a Project-to-Project reference to your class library.

You can build your library and the consuming app, and see that they all compile correctly.

What's not finished yet: if you try to run the result, you'll see that Json.Net (which was referenced by the class library) is needed by the app for it to run. And it's failing to pick up this fact. So you have to work around it in one of three ways...

  1. You can make the Console App itself use project.json. Then it will pick up the transitive dependencies correctly from its class library
  2. You can make the Console App itself have a NuGet reference to Json.Net, so the library gets pulled in after all.
  3. Instead of having your library has just a Class Library project, you could package it up as a NuGet package, one which pulls in Json.Net as a dependency via its .nuspec file. When you add a reference to the NuGet package from your class library, it will pull in Json.Net.