.NET Standard over PCL Xamarin.Forms.Core project - xamarin.forms

I'm reading that .NET Standard is now preferred over PCL class libraries to share code.
My question is should I use a .NET Standard library over a PCL for the core of a Xamarin Forms solution? Currently, it will target iOS and Android, but we are looking to Tizen for TV in the future.

You can also choose the best of both world by using .Net standard and the PackagetargetFallback attribute in order to be compatible with libraries not officialy compatible with it:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<PackageTargetFallback>portable-net45+win8+wpa81+wp8</PackageTargetFallback>
<PropertyGroup>
<!...>

.NET Standard will be the future, so if you can you should get on board now.
But be aware. If you're planning on using NuGet packages you could run into the situation that a package (or library from another source) does not support .NET Standard yet. Or the other way around is true as well. There are libraries that only support .NET Standard as of now, so you should either install an older version (with all the risks that come with it) or find an alternative path.
Also note; a lot is happening now in .NET Standard (and Core for that matter) land so be prepared for bugs, rough tooling and not all platforms being supported just yet.

Related

Is OxyPlot.Wpf compatible with .NET Core?

Does OxyPlot.Wpf work on .NET Core?
My application uses .NET Framework 4.8. I am considering switching to .NET Core 3.1.5 which was released in 2020 June.
Note OxyPlot has an assembly called OxyPlot.Core but it has nothing to do with .NET Core from what information I have gathered. OxyPlot.Core is "the core library... you also need to add a platform-specific OxyPlot package". This makes it seem that OxyPlot.Wpf depends upon OxyPlot.Core and in fact if you try to uninstall OxyPlot.Core the error will be "unable to uninstall OxyPlot.Core.2.0.0 because OxyPlot.Wpf.2.0.0 depends on it". The online documentation does not seem to tell you this but fortunately NuGet will prevent the uninstall.
This means OxyPlot.Core is the core of OxyPlot and its existence does not necessarily tell you anything explicit about .NET compatibility.
I'd say yes it is compatible. Based on the nuget link https://www.nuget.org/packages/OxyPlot.Wpf
Think you Will find OxyPlot works fine with Wpf .NET Core .. but I cannot say the same for a Winforms .NET Core project I have; at the present time I am having (the usual) enormous difficulty in making it work

Managing nuget packages for .net standard xamarin forms project

I am converting xamarin forms pcl to .net standard. In the project I use skia sharp and azure mobileservices.
My understanding was that if I reference these libraries in the .net standard class library and then add a reference to this .net standard class library in my android/ios/uwp projects all would be fine.
However it seems that I need to add the nuget packages for skiasharp and azure mobileservices to each project (android/ios/uwp). Is this indeed the case? if so, how is this better than using PCL?
I got the android project working, but I needed to add all the nuget packages to the android project.
I got the uwp project working without any nuget packages, which confuses me even further.
Using PCL and .NET Standard are basically the same - both are just API contracts or a subset of the full .NET Framework. But there is a MAJOR advantage to .NET Standard: .NET Standard has far more APIs - especially if you are using 1.3+ (netstandard1.3 has the System.IO APIs which aren't available in PCL).
With regards to NuGets, you typically still need to reference the NuGet package in all the app projects because some platforms have different implementations to take advantage of platform features. Think of .NET Standard as a subset of all the platform APIs - this is why SkiaSharp works just fine for some platforms. However, Android and iOS have a different implementation to take advantage of platform features.
Although you aren't doing Android development directly (since you are using Xamarin.Forms) you wouldn't have noticed something. If you JUST include the .NET Standard package, you get the basic SkiaSharp that can, for example, convert between a Xamarin.Forms color and a SkiaSharp color. However as a result of including the package in the android app, you can additionally convert from an Android color to a SkiaSharp color.
Personally, I always include all the NuGets into the app projects just to be safe.
Here are some docs that may help you:
https://learn.microsoft.com/en-us/dotnet/standard/net-standard

Convert .Net Framework 4.6.2 project to .Net core project

I Have a solution which contains the bunch of class libraries which is developed by .Net framework 4.6.2. I have to convert those class libraries into .Net core. Is there any best and fastest way to convert instead for rewrite the code.
This appears to be an official Microsoft resource for doing the migration. Summarized below:
(recommended) Retarget all projects you wish to port to target the .NET Framework 4.7.2 or higher.
(recommended) Use the .NET Portability Analyzer to analyze your assemblies and see if they're portable to .NET Core.
(recommended) Install the .NET API analyzer into your projects to identify APIs throwing PlatformNotSupportedException on some platforms and some other potential compatibility issues.
Convert all of your packages.config dependencies to the PackageReference format with the conversion tool in Visual Studio.
Create new projects for .NET Core and copy over source files, or attempt to convert your existing project file with a tool.
Port your test code.
Most of BCL is still the same API-wise, so conversion is definitely viable for consideration. Yes, there may be incompatibilities in your code (or more often - with your dependencies) and the easiest way to check is to try building it with .net core.
For more details about when to convert (and when to rewrite) or about options of performing the conversion you could follow this guide: Upgrading to .NET Core and .NET Standard Made Easy.
The easiest way to switch a .net framework project to a .netcore project is to open the csproj file and change the TargetFramework from something like this
<TargetFramework>net462</TargetFramework>
to something like this
<TargetFramework>netcoreapp3.1</TargetFramework>
You could also change it to .net standard, in case you want compatibility between .net core and .net framework consumer projects, by changing it to this:
<TargetFramework>netstandard2.0</TargetFramework>
You could target multiple frameworks like so:
<TargetFrameworks>net462;netstandard2.0</TargetFrameworks>
Ensure you use the correct version number and obviously depending on what this project already targets, things are going to break and will need fixing. For example, you can't use a .net framework class library with a .net core project.
A more detailed process is provided here:
https://learn.microsoft.com/en-us/dotnet/core/porting/
I just ran into the same error that you saw (as per your comment to #ImrePĆ¼hvel) when I was trying to migrate a CLI project from .NET Framework to netcoreapp3.1:
"The expression "[Microsoft.Build.Utilities.ToolLocationHelper]::GetPathToStandardLibraries(_, netcoreapp3.1, '', x64, '', '')" cannot be evaluated. Input string was not in a correct format. C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild\Current\Bin\Microsoft.Common.CurrentVersion.targets"
In my case, it was due to a misreading of the instructions.
The old framework had a tag:
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
This needs to be changed to:
<TargetFramework>netcoreapp3.1</TargetFramework>
NOT
<TargetFrameworkVersion>netcoreapp3.1</TargetFrameworkVersion>
I had simply changed v4.5 --> netcoreapp3.1 in the TargetFrameworkVersion tag without changing the tag name to TargetFramework.
So double-check that you changed:
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
to
<TargetFramework>netcoreapp3.1</TargetFramework>
(or whatever .NET Core version you want)
and NOT:
<TargetFrameworkVersion>netcoreapp3.1</TargetFrameworkVersion>

Project not compatible with netcoreapp2.0

I'm trying to add a full framework class library as a project reference to asp.net core 2.0 MVC project and getting the below error.
Project XYZ is not compatible with netcoreapp2.0 (.NETCoreApp,Version=v2.0).
Project XYZ supports: net462 (.NETFramework,Version=v4.6.2)
I have updated to the most recent version of Visual studio i.e, 15.3.5.
Is it even possible to reference 4.6.2 libraries in core 2.0 projects?
The first thing that you can try is to compile the library you want to consume as netstandard2.0.
Theoretically (according to the .net standard documentation), this will make it compatible with projects using net461 and later as well as netcoreapp2.0 and later.
In practice, sometimes you will end up with a problem with one of your dependencies that don't provide the same library version across different compilation targets.
In such cases you may simply need to add the .net core 2.0 as a target framework for the XYZ library.
The xml tag listing the targets is <TargetFrameworks> in the XYZ.csproj file and is not handled by the Gui of the project's properties.
So I would give a try at editing the XYZ.csproj by hand and add or replace what's listed as <TargetFrameworks> with netcoreapp2.0.
If you are adding it as additional target you need to separate them with ';' as in
<TargetFrameworks>net462;netstandard2.0;netcoreapp2.0</TargetFrameworks>
More details about this in this Microsoft doc.
Please keep in mind that this will trigger multiple compilations and will slow your build consequently...
It should be. Microsoft announced a ".NET Framework Compatibility Mode" with the release of .NET Standard 2.0. However, they didn't go into great detail about how it works exactly, or what to troubleshoot if it doesn't. Additionally, they only specific talk about it in relationship to Nuget packages, so it's possible there's some role Nuget is playing in the process, as well. Unfortunately, I've been unable to find any additional information about this feature outside of the announcement post.
That said, Microsoft's explicit recommendation is to not rely on the fact that your .NET Framework library may just happen to work in .NET Core; instead, you should be actively porting .NET Framework libraries you control to .NET Standard. I'd say you're likely going to spend more time trying to figure out why it doesn't "just work" than you would porting your code, so that it will definitely work, and be future-proof to boot.
The following solution worked for me.
Deleted bin and obj folders from all the projects in the solution, rebuild and if it still doesn't work try changing browser from debug options. for eg. If you already have chrome as default browser in Visual studio, switch to Edge or Firefox.

Convert .NET Core 2.0 class libraries to .NET Standard

Is there a way to easily convert a class library targeting .NET Core 2.0 to .NET Standard?
If I understand it correctly, if one wants to maximize the reusability of class libraries in projects targeting different .NET frameworks e.g. .NET Framework, .NET Core, Xamarin, etc., it's a better idea to target .NET Standard -- provided that all the required APIs are available in the version of .NET Standard that will be targeted.
This is the reason why I want to convert my class libraries from .NET Core 2.0 to .NET Standard 1.6 or .NET Standard 2.0.
In the project file, you can point target compilation to netstandard with the exact version.
Example of Proj.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.6</TargetFramework>
</PropertyGroup>
</Project>
...
Microsoft provides good documentation about targeting types.
Dotnet Standard is not a framework or a library, it is an abstract set of instructions: what functionality should have System.Array, String, List, and so on. Currently, there are different implementations: .NET Framework, .NET Core, Mono, Xamarin, Windows Phone. It means that different implementations can recompile and reuse your library targeting netstandard. It is a very good choice for a NuGet package.
You can play with the versions and find the minimum function set required for your library. Each Dotnet Standard extends the functionality of the previous version. Thus, the less the targeted version is selected the more platforms your library will support.
You can edit the csproj file (can be done inside VS by right-clicking on the project file) and change
<TargetFramework>netcoreapp2.0</TargetFramework>
to
<TargetFramework>netstandard2.0</TargetFramework>
Go to Project Folder
Open .csproj file
Replace your Target Framwork
netcoreapp2.2 TO netstandard2.0
See this picture to more clear
My five cents on this topic. I had to convert libraries already written in .Net Core 3.1 and 5.0. When you open a solution or add the project to your current .Net Standard solution it won't show the list of .Net Standard options.
The reason is you have 2 references to update in order to make it work. First, change the target framework in the .csproj file. For example, to switch to .Net Standard 2.1 I modified the file in the following way:
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
</PropertyGroup>
Second, change the project type reference in the Solution (.sln file) opening it with any editor or it won't recognize it either. The GUID for .Net Standard 2.1 is 9A19103F-16F7-4668-BE54-9A1E7A4F7556. If you have a different version of standard the trick is adding a new project, check the GUID for the project type and replace it in the solution file.
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = ...
EndProject

Resources