How to reference a specific version of NetStandard in project.json? - c#

I am struggling to figure out how to force the npm (Nuget Package Manager) to resolve a specific version of the NetStandard1.X platform.
I am trying to use Serilog but the version of .NetStandard it supports is v1.3. Is there any way to force this behavior in the project.json file via some command or switch or option.
{
"version": "1.0.0-*",
"dependencies": {
"NETStandard.Library": "1.6.0",
"Serilog": "2.2.1"
},
"frameworks": {
"netstandard1.3": {
"imports": "dnxcore50",
"dependencies": {
}
}
}
}
When you specify v1.3, you end up with v1.6. Surely there must be a way of doing this? I am trying to upgrade an old .net framework 4.6 class library that was using log4net and I am struggling with the basics here.
Error Dump:
Package Serilog 2.2.1 is not compatible with netstandard1.6 (.NETStandard,Version=v1.6). Package Serilog 2.2.1 supports:
- net45 (.NETFramework,Version=v4.5)
- net46 (.NETFramework,Version=v4.6)
- netstandard1.0 (.NETStandard,Version=v1.0)
- netstandard1.3 (.NETStandard,Version=v1.3)
One or more packages are incompatible with .NETStandard,Version=v1.6.
DotNet Core Version Info:
Product Information:
Version: 1.0.0-preview2-003131
Commit SHA-1 hash: 635cf40e58

Your project.json restores on my machine correctly, so I would guess there is something wrong with packages/versioning.
Please try to change Serilog dependency version:
"Serilog": "2.3.0-dev-00711"
Or as you suggested yourself during our chat, move the decency into framework tag:
"frameworks": {
"netstandard1.6": {
"imports": "dotnet5.6",
"dependencies": {
"Serilog": "2.3.0-dev-00711"
}
}
}

I'm not quite sure I understand what the question is or what exactly is the problem you're having.
But one thing that jumps at me about your project.json is that the version of NETStandard.Library should be 1.6.0, even if you're targeting netstandard1.3. (Yes, it's confusing.)

Related

Referencing Framework 4.6 Library in in .NET Core App 1.0.0 project

I'm been investigating options available to me for referencing existing .NET Framework 4.6 libraries in new .NET Core App projects.
As a proof of concept I've built a very simple .NET Framework 4.6 library, published it as a NuGet package and included it in a simple .NET Core Web app.
As of now the only way I seem to be able to get the project building and running is to remove the Microsoft.NETCore.App reference from the project.json dependencies block and replace the netcoreapp1.0 section from the frameworks property with a net461 block.
Full project.json below:
{
"dependencies": {
/*"Microsoft.NETCore.App": {
"version": "1.0.0",
"type": "platform"
},*/
"Microsoft.AspNetCore.Diagnostics": "1.0.0",
"Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
"Microsoft.AspNetCore.Server.Kestrel": "1.0.0",
"Microsoft.Extensions.Logging.Console": "1.0.0",
"FileIOLibrary_1_0_0_0": "1.0.0"
},
"tools": {
"Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final"
},
/*"frameworks": {
"netcoreapp1.0": {
"imports": [
"dotnet5.6",
"portable-net45+win8",
"net461"
]
}
},*/
"frameworks": {
"net461": {
"imports": [
"dotnet5.6",
"portable-net45+win8"
]
}
},
"buildOptions": {
"emitEntryPoint": true,
"preserveCompilationContext": true
},
"runtimeOptions": {
"configProperties": {
"System.GC.Server": true
}
},
"publishOptions": {
"include": [
"wwwroot",
"web.config"
]
},
"scripts": {
"postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
}
}
This basically means that all references are .NET Framework 4.6 libraries.
Anyway I've a few questions regarding other options available to me:
Is it possible to specify that only my imported library should be targeted towards the .NET 4.6 Framework and all other references should use .NET core? If so this would mean I could add the the Microsoft.NETCore.App reference back into the project.
If the above is not possible can I rebuild my library as a compatible .NET standard library (I believe version 1.6 is compatible between Framework 4.6 and Core 1.0.0)? I've been unable to see an option in Visual Studio to allow me to build libraries against the .NET Standard so would appreciate some pointers in this direction if its an option.
I'm afraid you cannot load a .NET 4.6.2 DLL into a .NET Core application.
The alternative plan
In some circumstances, you can write the code once and then have a project for .NET 4.6.2 and a project for .NET Core. Both projects point at the same code files but each project has a different framework target. Once you have that working, you can build a nuget package that has both the .NET 4.6.2 DLLs and the .NET Core DLLs in it, which will make deployment and build much simpler.
How to get the same code files building for each framework
Assuming you have a MyProject.csproj in a folder ./NET462/MyProject/ and a solution MySolution.sln.
First create an empty .NET Core Library. We'll call it MyProject.Core and we'll put it in ./Core/MyProject.Core/. We'll also have a Solution too, call that ./Core/MySolution.Core.sln.
Now copy all the files from the original ./NET462/MyProject/ into ./Core/MyProject, including the .csproj. Copy the solution too, they're going to live side-by-side.
If you load the original solution right now then Visual Studio will throw errors because there will be a conflict between the project.json (which is used by the Core project) and the .csproj (which is used by the .NET 4.6.2 project).
To stop that, create a new file called MyProject.project.json. This acts as a companion to the project.json when the .NET 462 project is loaded. Put the following into it:
MyProject.project.json
{
"version": "1.0.0-*",
"description": "My Class Library",
"authors": [
"Your Name"
],
"tags": [
""
],
"projectUrl": "",
"licenseUrl": "",
"runtimes": {
"win": {}
},
"frameworks": {
"net452": {} // You might want net462
},
"dependencies": {
"Newtonsoft.Json": "9.0.1" /// Just an example of a nuget package
}
}
Your .NET 4.6.2 project should now build just as before.
Now open the Core solution (it's OK to have both Visual Studios open at the same time) and you'll see that all the files are added in there. Under .NET Core / xproj, Project.json files are include-by-default. You will need to ignore the files specific to .NET 462, which are the .csproj and MyProject.project.json.
It probably won't build until you get the nuget packages added.
How to get .NET Core and .NET into the same Nuget
Once each solution is built in Release mode, you will have two outputs, a DLL for each of the frameworks. You can change the name of the DLLs in the project files (.csproj and project.json respectively) but nuget doesn't care.
Create a package.nuspec file and put the following in it:
<!-- language: lang-xml -->
<?xml version="1.0"?>
<package>
<metadata>
<id>MyProject</id>
<version>1.0.0</version>
<authors>Me</authors>
<owners>Me</owners>
<projectUrl></projectUrl>
<iconUrl>FILL ME IN</iconUrl>
<description>FILL ME IN</description>
<copyright>FILL ME IN</copyright>
<releaseNotes>First attempt</releaseNotes>
<tags>FILL ME IN</tags>
<dependencies>
<group targetFramework="dotnet">
<dependency id="Newtonsoft.Json" version="9.0.1" />
</group>
<group targetFramework="net452">
<dependency id="Newtonsoft.Json" version="9.0.1" />
</group>
</dependencies>
<frameworkAssemblies>
<frameworkAssembly assemblyName="System.Core" targetFramework="net452"/>
<frameworkAssembly assemblyName="System.Core" targetFramework="dotnet" />
</frameworkAssemblies>
</metadata>
<files>
<file src="Core\MyProject\bin\release\MyProject.dll" target="lib/net452" />
<file src="Core\MyProject\bin\release\MyProject.Core.dll" target="lib/dotnet" />
</files>
</package>
Use this to build your nuget package and when including in your main system, nuget will serve the correct package.
Bigger Example
My JsonApi library does this and additionally it has two Web projects, one for .NET 4.6.2 and one for .NET Core because they use different base classes. The main shared library is used by both.
Big caveat
Some libraries that your .NET 4.6.2 rely upon will not be available to your Core application. The two times I've done this it has been System.Web that has caught me out. System.Web in .NET 4.6.2 is really a wrapper for IIS. The best way to find out is to try merging the projects above and keep adding nuget packages to project.json until you hit something that doesn't exist for Core.
Things are changing
The .NET team in May 2016 said that they were moving away from using the project.json at the end of 2016. At which point, I imagine that these problems might go away as visual studio should be able to handle two kinds of .csproj living side by side. Depending on your commercial situation, I'd wait for that change!

What's difference between .NetCoreApp and .NetStandard.Library?

.Net Core 1.0 has been released couple days ago, and i've started playing with it. I've created simple solution, with one project (class library => .NetStandard.Library) and second, console application (.NetCoreApp). The point is, console application has reference to library, but i cant use types form that library. Are those two frameworks incompatible? Am i missing something?
project.json for console application:
{
"version": "1.0.0-*",
"buildOptions": {
"emitEntryPoint": true
},
"dependencies": {
"ConsoleApplicationLibrary": "1.0.0-*",
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.0"
}
},
"frameworks": {
"netcoreapp1.0": {
"imports": "dnxcore50"
}
}
}
project.json for library:
{
"version": "1.0.0-*",
"dependencies": {
"NETStandard.Library": "1.6.0"
},
"frameworks": {
"netstandard1.6": {
"imports": "dnxcore50"
}
}
}
I've figured it out, that it works, and code compiles, but visual studio still highlights types from library as unknown.
The most likely issue is that .Net Core is expecting ConsoleApplicationLibrary to be a NuGet package. If you want to reference a project, use "ConsoleApplicationLibrary": {"target": "project", "version": "1.0.0-*"}.
After you do that, don't forget to restore packages.
Ok, it's strange, but after disabling resharper, restarting VS and rebuilding solution, it works fine. It seems there is prolem with resharper support for .net core. (resharper v.9.1.3). From this: resharper ultimate blog i understand that only ultimate version supports .net core for now.
.NetCoreApp is a platform and .NetStandard.Library is a library supposed to be cross platform (portable class library) for various .NET platforms runtimes.
You can include a direct reference (package) of NetStandard.Library in any of your .NET platform project that is supported, for ex .NETCoreApp (Dot Net Core 1.X)
Reference: https://learn.microsoft.com/en-us/dotnet/articles/standard/library
I had the same issue and it turned out I needed to update Resharper to it's latest version. I had v9.1.1 so I updated it to 2016.3.2 and that fixed the issue.

How can I use .Net Core Class Library (.NetStandard v1.5) into .Net Framework 4.6.2 Application

According to Mapping the .NET Platform Standard to platforms .NET Platform Standard 1.5 have to be compatible with .NET Framework 4.6.2. I have tried to use it (make new .NET Platform Standard class library, then new .Net Framework 4.6.2 console application), but the library is not recognized. What I am doing wrong?
project.json in class library:
{
"version": "1.0.0-*",
"dependencies": {
"NETStandard.Library": "1.5.0-rc2-24027"
},
"frameworks": {
"netstandard1.5": {
"imports": "dnxcore50",
"buildOptions": { "embed": "true" }
}
}
}
If you get the latest .net core RTM release and the Update 3 VS tooling, things are a little nicer than they were during the RC period. Still don't have easy project references from csproj referencing xproj - but, you can get things to talk by packing up the xproj output into a nuget package, then using the package manager to install that package. Also, you shouldn't need the imports on the framework, nor the dependency on netstandard.library, at least I don't. Here's how I've done it:
Create a .cmd file which will package the nuget files and two copy the output files to the folder where the package manager is expecting them. Here's that script, I call it makeNuget.cmd:
IF "%1" == "%2" (
dotnet pack --no-build --configuration %1 -o ../%3
xcopy %4 "...\%3\lib\%5\" /Y
)
Add a postbuild script in the project.json of the xproj to run the script
"scripts": {
"postcompile": [
"makeNuget.cmd %compile:Configuration% Release packages\%project:Name% %compile:OutputDir% %compile:TargetFramework%"
]
}
This should leave you with a nuget package in the packages\[projectName]\ folder at the root of your solution, with the binaries in the packages\[projectName]\lib\[targetFramwork]\ folder
Now, you need to add the packages folder as a package source, so first open the package manager console, then click the little gear to add a package source (or Ctrl+Q, package sources, Enter). Then click the add button, name this source, browse or type in the packages directory and hit ok.
In the package manager console, make sure both your package source and project are selected in the drop downs at the top.
install-package [your package name]
AFAIK, that's as good as it gets at the moment.
Do you really need .Net Framework 4.6.2 app?
I just created PCL (Portable class library) targeting .NETStandard1.4 and I can use it in WPF app which is targeting .NET Framework 4.6.1.
Here is how my project.json looks like in PCL project:
{
"supports": {},
"dependencies": {
"Microsoft.NETCore.Portable.Compatibility": "1.0.1",
"NETStandard.Library": "1.6.0"
},
"frameworks": {
"netstandard1.4": {}
}
}

Dependency issues migrating project from ASP.NET 5 RC1 to ASP.NET Core 1.0

I am having a hard time converting my asp.net (core) app from dnx46 to .netcoreapp1.0 because of two particular dependencies ( Microsoft.Azure.ServiceBus and System.IO.Ports.SerialPort )
Being positive, I'm making the bet that these feature will eventually land on .net core one day.. but in the meantime, I found that converting my app from moniker dnx46 to .netstandard1.3 allows me to resolve the ServiceBus dependency.
Resolving System.IO.Ports.SerialPort however is still an issue and I don't understand how to make this work. I was hoping that importing net462 framework in .netstandard1.3 moniker, would allow to find the System.IO.Ports.SerialPort object but it does not.
What am I missing ?
For reference, there's my project.json :
{
"dependencies": {
"Microsoft.NETCore.App": {
"version": "1.0.0-rc2-3002702",
"type": "platform"
},
"Microsoft.NETCore.Platforms": "1.0.1-*",
"Microsoft.EntityFrameworkCore": "1.0.0-rc2-final",
"Microsoft.EntityFrameworkCore.Sqlite": "1.0.0-rc2-final",
[...more stuff...]
},
"frameworks": {
"netcoreapp1.0": {
"dependencies": {
// To be restored when they'll become available on .net core
// "Microsoft.WindowsAzure.ConfigurationManager": "3.2.1",
// "WindowsAzure.ServiceBus": "3.2.1",
}
},
"netstandard1.3": {
"buildOptions": {
"define": [ "INCLUDE_WINDOWSAZURE_FEATURE" ]
},
// Imports of net462 fixes loading of
// - NewtonSoft.Json
// - System.Runtime.Loader for "Microsoft.NETCore.App"
"imports": [
"net462"
],
"dependencies": {
"Microsoft.NETCore.Portable.Compatibility": "1.0.1-rc2-24027"
"Microsoft.WindowsAzure.ConfigurationManager": "3.2.1",
"WindowsAzure.ServiceBus": "3.2.1",
}
}
}
}
Resolving System.IO.Ports.SerialPort however is still an issue and I don't understand how to make this work. I was hoping that importing net462 framework in .netstandard1.3 moniker, would allow to find the System.IO.Ports.SerialPort object but it does not.
You can't reference System.IO.Ports.SerialPort when targeting .NET Core or .NET Standard, because this contract only exists in the full .NET Desktop framework.
This library might be eventually ported but in the meantime, you'll have to use .NET Desktop (e.g net462) instead of .NET Core.
Remove netcoreapp1.0 and netstandard1.3 and add net462 and it should work.
If you plan on deploying to a windows box and targeting net452, then simply take on a dependency on net452. I put together a migration guide to share my upgrading experiences, perhaps it might help? I initially had this misunderstanding that I would take a dependency of netstandard1.* and then "import": "net4*", David Fowler laughed at me and said something to the extent of "dude that's do wrong!". :P
You should change your project.json frameworks to look like this:
"frameworks": {
"net462": { }
}

.NET Core Dependencies and Frameworks Understanding

I have been working on .NET Core from a few weeks now. At first it was a great overhaul from Microsoft to the old .NET way of doing things. But now its getting on my nerves. Below is my original global.json:
{
"projects": [ "src", "test" ],
"sdk": {
"version": "1.0.0-rc1-update1",
}
}
This is my project.json:
{
"version": "1.0.0-*",
"compilationOptions": {
"emitEntryPoint": true
},
"dependencies": {
"Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final",
"Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final",
"Microsoft.AspNetCore.StaticFiles": "1.0.0-*",
"Microsoft.NETCore.Platforms": "1.0.1-*"
},
"commands": {
"web": "Microsoft.AspNet.Server.Kestrel"
},
"frameworks": {
"dnxcore50": { }
},
"exclude": [
"node_modules"
],
"publishExclude": [
"**.user",
"**.vspscc"
]
}
And here is my hosting.json:
{
"webroot": "wwwroot"
}
I have created an Empty ASP.NET Core 1.0 Web Application Project, all I am trying to do is create an AngularJs application. But I cannot access the wwwroot directory since I am not able to:
app.UseDefaultFiles();
app.UseStaticFiles();
I removed the dnx451 from my original project.json and also changed the global.json to:
{
"projects": [ "src", "test" ],
"sdk": {
"version": "1.0.0-rc1-update1",
"runtime": "coreclr",
"architecture": "x64"
}
}
Error:
Error NU1002 The dependency Microsoft.AspNetCore.StaticFiles 1.0.0-rc2-20248 in project QMS.UI does not support framework DNXCore,Version=v5.0. QMS.UI ..\QMS.UI\src\QMS.UI\project.json
I have read a lot of blogs and stackoverflow answers. Can anybody tell me in very high level way how does we:
Effectively find a valid package, that will suite our target framework.
Effectively make all frameworks (if listed in the project.json) happy with that dependency notation? (Sometimes I get an error, its available for dnx451 but not dnxcore50) (Should I use the #if dnxcore50... etc notations?)
Please help! I am going through a similar trouble in another project based on .NET Core.
The static file dependency is form RC2 and is not compatible with RC1 you use in rest of your project.
Either you use all packages from RC1 or all from RC2, but be aware that RC2 dependencies often break (one package requires version xyz, where other package is not yet updated and requires old library but due to API changes can't work with the newer version).
This are RC1 packages
"Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final",
"Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final",
This are RC2 packages (you can recognize them on their name, Microsoft.AspNet.* packages got renamed to Microsoft.AspNetCore.* some time during RC2 cycle
"Microsoft.AspNetCore.StaticFiles": "1.0.0-*",
"Microsoft.NETCore.Platforms": "1.0.1-*"
Effectively find a valid package, that will suite our target framework.
First step is to target only the same versions. If you need a stable environment use RC1 until RC2 is released. However, be aware that there are quite a few breaking changes. Check out the ASP.NET Core GitHub annoucements (mostly breaking changes) for more information.
Effectively make all frameworks (if listed in the project.json) happy with that dependency notation? (Sometimes I get an error, its available for dnx451 but not dnxcore50) (Should I use the #if dnxcore50... etc notations?)
Depends on the assemblies you need. Some have compatible api with both target platforms, but most don't. Usually that's how you would switch out platform dependent assemblies/code.
Be aware that there is a difference if you use a Class Library (Package) or .NET Core application (Webproject, unit test project).
For RC1, the monikers are dnx451 (or dnx452, dnx46) for full .NET Framework targeting and dnxcore50 for .NET Core. For Class Libraries however, you have to use net451 (or net452/net46) for full .NET Framework target and dotnet5.x (x=1-4, i RC2 also 5) for .NET Core.

Categories