Can you target .NET Framework, .NET Standard and .NET Core in a NuGet package? - nuget-package

I'm new to creating NuGet packages and have only been playing around with them for a couple of days, as it now stands I've tested my package on .NET Frameworks 3.5 through 4.8 successfully.
By the way, this is the package: https://www.nuget.org/packages/ExcelFromList/1.0.4
My package relies on EPPlus, which is what I use as the engine. If you search for EPPlus you will see that it states that it can be installed on .NET Framework, .NET Standard, and .NET Core, I have tested this and it's correct.
So I'm not sure how to pull this off.
This is the info on my project:
Project is .NET 3.5
Using nuget.exe to create the NuGet package
Using .nuspec file for package creation (nuget pack <.nuspec file>)
Only NuGet package installed in project is EPPLus
This is my .nuspec file:
<?xml version="1.0" encoding="utf-8" ?>
<package>
<metadata>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<id>ExcelFromList</id>
<version>1.0.4</version>
<title>ExcelFromList</title>
<description>Straightforward and easy way to create stylized excel workbooks from lists. Add an image, title, subtitles and overal cell styles/formats. Uses the EPPlus engine.</description>
<releaseNotes>Succesfully tested on .NET frameworks from 3.5 through 4.8</releaseNotes>
<authors>Raul Marquez</authors>
<owners>Raul Marquez</owners>
<copyright>Copyright 2020 Raul Marquez</copyright>
<projectUrl>https://github.com/RaulMarquezInclan/ExcelFromList</projectUrl>
<license type="expression">GPL-3.0-only</license>
<tags>excel list listtoexcel</tags>
<dependencies>
<dependency id="EPPlus" version="5.1.0" />
</dependencies>
</metadata>
<files>
<file src="bin\Debug\net35\ExcelFromList.dll" target="lib\net35" />
<file src="bin\Debug\net35\ExcelFromList.xml" target="lib\net35" />
</files>
</package>
Building the package with that configuration throws me this warning:
WARNING: NU5128: Some target frameworks declared in the dependencies
group of the nuspec and the lib/ref folder do not have exact matches
in the other location. Consult the list of actions below:
- Add a dependency group for .NETFramework3.5 to the nuspec
However, as I stated before, it still installs and runs just fine throughout the different .NET Framework versions.
When attempting to install it on .NET Standard or .NET Core it will install my dll correctly but it won't install EPPlus, which is a dependency of my package. On the .NET Standard side, I only have to manually install it and all is good, on the .NET Core side after doing the same it tells me that the executable cant run in the project.
So, where I'm confused is on how to also make them available to .NET Standard and .NET core, from searching around I've gotten hints about converting it to a .NET standard in the first place, or having three different dlls each corresponding the the different technologies and specifying them in the files section of the .nuspec file, etc.
Can anyone please point me in the right direction?
EDIT: By the way, when looking at the EPPlus package this is what we see:
Thanks.

You can, if you upgrade your .csproj file to the "new" .csproj file format. I'd highly recommend you do that; the new project format is greatly simplified and easier to use.
In this new format, you can target multiple frameworks, like this:
<PropertyGroup>
<TargetFrameworks>netstandard2.1;netstandard2.0;net45;net40;net35</TargetFrameworks>
</PropertyGroup>
The EPPlus project file is a great example of how to do multi-targetting.
You can then build your package by running dotnet pack, and it will automatically create a NuGet package which targets all of the versions of .NET listed in TargetFrameworks.
You will need to use the .NET Core SDK to build your project, but you can still run your package on desktop .NET.

Related

Why project cannot find references for WebJobs.Core?

Following this I created a console .Net Core 2.1 application, and I'm using Microsoft.Azure.WebJobs.Core NuGet v. 3.0.0-beta5. For some reason the project can't compile as it says it cannot find the assemblies. Why on earth?
Actually, you do not need to install Microsoft.Azure.WebJobs.Core NuGet v. 3.0.0-beta5.
You could just try to install Microsoft.Azure.WebJobs version 3.0.0-beta5. Then it will work.
This Microsoft.Azure.WebJobs package contains the runtime assemblies for Microsoft.Azure.WebJobs.Host. It also adds rich diagnostics capabilities which makes it easier to monitor the WebJobs in the dashboard. For more details, you could refer to this article.

TFS Tests do not match framework settings

I am attempting to move a solution from TFS 2012 to TFS 2018 SP2RC2 but I can't get the unit tests to run correctly. All projects have been re-targeted to 4.7.1 and are built as x86 platform. We have a testsettings file that supplies nothing but deployment items. I am using the new VSTest Platform Installer task (as directed by MS) and the VS Test Task. At the start of the test run I get the following message:
Test run will use DLL(s) built for framework .NETFramework,Version=v4.5 and platform X86. Following DLL(s) do not match framework/platform settings.
So all of the test are skipped as they target 4.7.1. Where is this 4.5 setting coming from? I cannot find it specified anywhere and can't figure out how to change it.
There is a /Framework: parameter that you can specify to VSTest.
In your case, you should specify /Framework:.NETFramework,Version=v4.7.1
See more at https://msdn.microsoft.com/en-us/library/jj155796.aspx?f=255&mspperror=-2147217396
To add this parameter in a Azure DepOps yaml pipeline, use the otherConsoleOptions argument
- task: VSTest#2
otherConsoleOptions: '/Framework:.NETFramework,Version=v4.7.1'
The fix I found for this in Visual Studio is way easier than I thought:
Exit all instances of VS
Open your project folder in Windows Explorer, find the .vs folder, delete it
Restart VS, the folder rebuilds itself, tests work again.
Apparently there are some settings that the NUnit plugin stashes in this folder and they are in binary so you can't edit them. This happened to me after I updated to NUnit3TestAdapter version 3.17.
I had trouble running a test project developed on another machine where no tests where able to be run using the MSTest test runner. In addition to message in your question I also got the messages:
Make sure that test discoverer & executors are registered and platform
& framework version settings are appropriate and try again.
Discover test finished: 0 found
In my case I resolved it by unloading and updating the .csproj file adding the following import directly under the root Project tag.
<Import Project="..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.props" Condition="Exists('..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.props')" />
Hope this answer will help save you some time.
I got this error using Visual Studio 2019 with NUnit 3.12.0:
Test run will use DLL(s) built for framework
.NETFramework,Version=v4.5 and platform X86. Following DLL(s) do not
match framework/platform settings.
Project.UnitTests.dll is built for Framework 4.5.2
and Platform AnyCPU.
Installed NUnit3TestAdapter 3.13.0 and then everything started working. Did not need to modify Framework version or CPU settings.
Had the exact same issue as Bill, working on legacy code in VS2019, nothing else had worked. I simply changed the Run Settings to use the Auto Detect.
In the menu go to Test -> Configure Run Settings -> Auto Detect runsettings File
For me skipping tests in local VS2022 run was related to testsettings file. I deleted .vs folder of my project then selected
Test ->Configure Run Settings -> Select Autodetect run settings file
After that I can debug unit tests
TLDR: If you use *.runsettings file for your test projects, try removing TargetFrameworkVersion node
I had similar problem but with .Net Core
Test run will use DLL(s) built for framework
.NETFramework,Version=v4.0 and platform X64. Following DLL(s) do not
match framework/platform settings. MyProject.Tests.dll is
built for Framework .NETCoreApp,Version=v3.1 and Platform AnyCPU.
Turns out there was another problem. For my other .NET Framework test projects I had defined *.runsettings file
And in this file I had
<?xml version="1.0" encoding="utf-8"?>
<RunSettings>
<!-- Parameters used by tests at runtime -->
<TestRunParameters>
<Parameter name="ConnectionString" value="Data Source=localhost;Initial Catalog=MyDatabase;Integrated Security=True" />
</TestRunParameters>
<RunConfiguration>
<!-- Framework35 | [Framework40] | Framework45 | FrameworkCore10-->
<TargetFrameworkVersion>Framework40</TargetFrameworkVersion>
</RunConfiguration>
</RunSettings>
Supported values for TargerFrameworkVersions based on https://learn.microsoft.com/en-us/visualstudio/test/configure-unit-tests-by-using-a-dot-runsettings-file?view=vs-2019
are:
FrameworkCore10 for .NET Core sources, FrameworkUap10 for UWP-based
sources, Framework45 for .NET Framework 4.5 and higher, Framework40
for .NET Framework 4.0, and Framework35 for .NET Framework 3.5.
But for Core 3.1, FrameworkCore10 doesnt work!
So I removed node TargetFrameworkVersion completely
I had the same problem in VS 2019 on a legacy project.
Restarting Visual Studio did not help, nor did build as Release then rebuild as Debug, nor did deleting the .vs folder. I did those things and still was unable to run tests, getting a message like the OP's during test detection each time. I mention these here for completeness.
I deleted the LocalTestRun.testrunconfig file and the *.vsmdi file from Solution Explorer, cleaned and rebuilt the solution, and the unit tests worked again.
I was running into the same issue with the Visual Studio Test Task version 2 in an Azure Devops 2019 pipeline after a .csproj test project was upgraded from .NetFramework 4.6.1 to .NetCore 3.1.
The fix for us was to be more specific when specifying the test files. The default of **\*test*.dll was finding several other assemblies with "test" in their names that didn't exist before the upgrade. Using an explicit **\<MyTestAssemblyName>.dll fixed the issue.

The "Microsoft.CodeAnalysis.BuildTasks.Csc" task could not be loaded

I'm trying to publish a newly created asp.net 4.6 web project to Azure web apps and receiving the following error:
remote: D:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.CSharp.targets(316,9): error MSB4062: The "Microsoft.CodeAnalysis.BuildTasks.Csc" task could not be loaded from the assembly D:\home\site\repository\packages\Microsoft.Net.Compilers.1.0.0\build..\tools\Microsoft.Build.Tasks.CodeAnalysis.dll. Could not load file or assembly 'Microsoft.Build.Utilities.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified. Confirm that the declaration is correct, that the assembly and all its dependencies are available, and that the task contains a public class that implements Microsoft.Build.Framework.ITask. [D:\home\site\repository\WebApp\WebApp.csproj]
Everything builds fine via Visual Studio 2015 on my local machine. I thought Azure web apps were all set to support VS 2015 RTM upon release, but it would appear they do not have MSBuild 14.0 installed. Is there a work around or a roadmap for this problem?
Here was the fix for me.
Using Nuget Package Manager, remove these two packages if referenced:
Microsoft.CodeDom.Providers.DotNetCompilerPlatform
Microsoft.Net.Compilers
After that, run a rebuild. This ensured that the build was not trying to use a specific build exe. Click here for the
Diff against previous revision
In my case I have to edit my .csproj file and find below lines and delete them
<Error Condition="!Exists('..\packages\Microsoft.Net.Compilers.1.0.0\build\Microsoft.Net.Compilers.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Net.Compilers.1.0.0\build\Microsoft.Net.Compilers.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.0\build\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.0\build\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props'))" />
Now everything is fine,
Azure Web Apps doesn't support ASP.NET 4.6 yet. It's on it's way though, so stay tuned.

Force NuGet to download packages built to project .Net version

This should be a simple question but I can't seem to find the answer anywhere.
I've got a project that I'm building to .Net 3.5. I'm trying to include Newtonsoft JSON.Net as a reference, but NuGet is installing a version built to .Net 4.0. This makes it impossible for me to use my compiled assembly in an environment that does not support .Net 4.0.
Is there any way to configure NuGet so that it ensures that the reference is not built to a version of .Net beyond the project settings?
Maybe you can use this answer to a similar question:
Download old version of package with nuget
It says that you can install an old version of a package
You can try to install a version compatible with .NET Framework 3.5, and it will be solved!
;) I hope this helps
NuGet will use the project's target framework to pick the correct assembly from the NuGet package. You cannot override this behaviour.
The latest version of the Json.NET NuGet package (6.0.1) contains an assembly specifically for .NET 3.5 so NuGet should automatically pick that one if your project has a target framework of 3.5.
Changing my project's target framework to 3.5 results in the following element being added to the project:
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
This is what NuGet uses to determine which assembly to use.
When Json.NET is installed into this project the Newtonsoft.Json.dll file is referenced from the packages\Newtonsoft.Json.6.0.1\lib\net35 directory. That assembly targets .NET 3.5

Microsoft.Threading.Tasks.Extensions in Xamarin Mono projects

I have built a NuGet package for my Simple.OData.Client with support for Xamarin Android and iOS. This library uses Microsoft.Bcl.Async. Tests using Android and iOS simulator went OK, but when I install this new NuGet package into another project, it fails to compile Droid/Touch projects with the following message:
C:\Program Files (x86)\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(720,2): error : Exception while loading assemblies: System.IO.FileNotFoundException: Could not load assembly 'Microsoft.Threading.Tasks.Extensions, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. Perhaps it doesn't exist in the Mono for Android profile?
C:\Program Files (x86)\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(720,2): error : File name: 'Microsoft.Threading.Tasks.Extensions.dll'
Of course there is no Microsoft.Bcl.Async pack (yet) for Mono platforms, on the other hand since the library tests pass on these platforms, I guess this more of a challenge to make Visual Studio happy rather than do some code modification.
Has anyone managed to use on Mono PCLs dependent on Microsoft.Bcl.Async?
Generally, if the code in your package depends on another NuGet package, you need to declare a package dependency so that anyone installing your package will get the one you depend on too. That should take care of issues like this.
However, in this case it is a lot more complicated. Since Microsoft.Bcl.Async doesn't support Mono platforms, you can't declare that package dependency (or if you did it would always fail to install). Unfortunately the license for Microsoft.Bcl.Async restricts it to "Windows platforms". I'm not a lawyer but I think that means you shouldn't distribute Microsoft.Threading.Tasks.Extensions.dll as part of your package. Finally, there's no official PCL support for Mono platforms yet, so if you do come up with a solution that works now it may change when official PCL support comes out.
If you want to attempt getting this to work, what you basically need to do is create your own DLLs with the same names as are in Microsoft.Bcl and Microsoft.Bcl.Async for use on Mono platforms. In those assemblies, put type forwards for the types that Mono already implements (which should probably be the types in the System.* DLLs), and create an implementation of your own for the other ones (the AsyncBridge source code is useful for this). This is what I did for one of my BUILD 2012 PCL demos. The code for that is here. AsyncFacades and AsyncBridge are the relevant projects.
For those stumbling into this issue when getting the Simple.oData.Client from nuget, just install the following packages from nuget:
Microsoft Bcl Async Portable
Microsoft Bcl Async
I believe I've found the problem.
Earlier I had the following line in Simple.OData.Client nuspec file:
<file src="Simple.OData.Client.Core\bin\Release\Microsoft.Threading.Tasks.Extensions.dll" target="lib\portable-net403+win8+sl5+wp8+MonoAndroid16+MonoTouch40\Microsoft.Threading.Tasks.Extensions.dll" />
This is not how it should be because Microsoft.Bcl.Async should have taken care of copying Tasks.Extensions.dll. I reported this to Microsoft and expected this to be fixed in the RTM version of Microsoft.Bcl.Async. Apparently it was not, so all NuGet packages dependent on Microsoft.Bcl.Async should still copy this file. Then it will work.
for who has the same issue I think you can downgrade
System.Threading.Tasks.Extensions 4.4.0

Resources