Xamarin.Forms: Move to .NET Standard - xamarin

My Xamarin.Forms project targets PCL profile 259. I recently read a lot of moving to .NET Standard, but it looks very painful to do.
Currently I develop in Visual Studio 2015 Update 3. But will give VS 2017 a try soon.
My solution consists of:
Common PCL library
Android specific project
iOS specific project
My Questions:
How can I convert from Profile 259 to latest .NET Standard?
Is there some official converson guide from Xamarin / Microsoft Team already available?
My Xamarin.Forms Android and iOS Apps are built in VSTS. Does VSTS support .NET Standard or would I end up in build errors?
Thanks in advance for any good solution.

To change a PCL to .NET Standard you just need to go to the Properties of your PCL and select Target .NET Standard Platform
Then create a project.json file, if it didn't already create one for you and insert the following.
{
"supports": {},
"dependencies": {
"NETStandard.Library": "1.6.0",
"Xamarin.Forms": "2.3.4.192-pre2"
},
"frameworks": {
"netstandard1.3": {
"imports": "portable-net45+win8+wpa81"
}
}
}
You need the imports to allow non .NET Standard libraries to be added.
In VS 2017 it gets different. While the above will continue to work, you can have a full .NET Standard library as a csproj (no longer an xproj), and have it happily work with Xamarin.
However, there is no automatic conversion (that I know of), so what I normally do, is edit the csproj and completely replace it with the following. Just delete everything in that file and put the following.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.3</TargetFramework>
<AssemblyName>MyLibraryName</AssemblyName>
<PackageId>MyLibraryName</PackageId>
<NetStandardImplicitPackageVersion>1.6.0</NetStandardImplicitPackageVersion>
<PackageTargetFallback>$(PackageTargetFallback);portable-win+net45+wp8+win81+wpa8</PackageTargetFallback>
</PropertyGroup>
</Project>
You will then have to add your references and NuGet packages manually, again. With the PackageTargetFallback, this line is similar to the imports in project.json.
In regards to VSTS, I know that the first method with VS2015 works just fine, as I have done it myself. The VS2017 method should work with VSTS, however I haven't personally tried that just yet.

Related

How to get NuGet options in Visual Studio 2017 Community?

I am struggling with creating NuGet packages. I am using Visual Studio 2017 Community edition.
I have seen a couple of videos that show a "Pack" option on the menu when right-clicking the project in Solution Explorer. However, I do not have that option. Is this one of the features in the other (non-Community) versions of Visual Studio? I believe I have also seen a "create NuGet package on build" option mentioned somewhere. I cannot find that either.
I have tried various ways of using nuget, dotnet, and msbuild from the command line(s), but haven't had much success. Very frustrating.
Any help is appreciated.
If you really want to use Visual Studio, I would recommend installing an extension that helps you with that problem. For example, this one. The options people have in videos depend on the extensions they have installed. For you, it is the same.
Alternatively, just use the command-line tooling for this as explained here or for .NET Core here or here.
dotnet/msbuild pack is only available for SDK-style projects, but I believe works for all versions of Visual Studio, as well as on the command line. .NET Core introduced these SDK-style projects, which can be identified by <Project Sdk="Microsoft.NET.Sdk">. If your project (.csproj if it's a C# project) doesn't have the Sdk property or import Microsoft.NET.Sdk in either of the two other ways, then it's not an SDK style project and doesn't support packing in this way. Another obvious difference between the two styles of projects is that SDK projects are only a few lines long from the new project template and don't list files in the project, whereas old style projects are typically a full screen long, even from a new project template with only a single class file, and it does list individual files in the project. If you want to continue with this project type, you'll need to use nuget.exe pack and you'll probably want to create a .nuspec file to define some of the package metadata.
However, using SDK style projects is the future, it just takes time for all of Microsoft's existing project types to migrate. It's much simpler to use, so personally I would avoid old style projects unless you're using a project type (like ASP.NET, not ASP.NET Core) that doesn't support it.
All of this is confusing for anyone new to the .NET ecosystem. My recommendation is 1. when you install Visual Studio, when making your workload selections, make sure in the component list that .NET Core is selected, whatever the newest version of .NET Core that is available at the time of installation. When creating a new project in Visual Studio, always select the .NET Core version, or .NET Standard version of any new project template, even if you want to target the (Windows) .NET Framework, in which case you edit the .csproj and change <TargetFramework>netstandard2.0</TargetFramework> to <TargetFramework>net45</TargetFramework>, although I would recommend multi-targeting possible by adding a s to the element name and using a semi-colon separated list: <TargetFrameworks>net45;netstandard2.0</TargetFrameworks>. So, avoid the "Class Library (.NET Framework)" template, instead use "Class Library (.NET Standard)" and then change the target if you have to.
#zivkan led me down the right path. Changing my project types to .Net Core from .Net Framework made all the options I mentioned in my original post available. No extensions were needed.
My .Net Core class library project now has the Pack and Publish options available on the project's context menu. In addition, there is a another tab (Package) on the project properties page. On that page there is a "Generate NuGet package on build" option along with version, name, tags and other properties.
I have done much .Net framework development, but have been ignoring .Net Core and the newer options. I guess I need to dig in and learn about them.

Is it possible to avoid ADK uses in Xamarin?

I need to implement few features, however, they do not seem to be possible, and I don't have a lot of implementation time.
I have a solution PCL (.NET 4.5, Profile=111) and for some reasons (that I don't understand from hours now), I can't install the following packages :
Stripe (The only one that can be installed is Stripe.net, but I can only install it on Android and iOS, not on the PCL part..)
Cloudinary (I tried all of them and... It's not compatible with .NET 4.5, Profile=111)
Do you have any idea or any work around to make it work? I need Stripe for payments and Cloudinary for images hosting. It's already what the company is using so, I have to adapt.
I was thinking about don't use any sdk and just do everything by myself, is it allowed/possible?
Both of that packages have .Net Standard targets so i would prefer to use new *.csproj vs2017 format with library targeting .Net Standard. That is not an PCL that targets .Net Standard, this is not an PCL at all.
.Net Standard library with new csproj format have some advantages like:
Ability to install old nuget packages that targeting platforms as well as new packages that targeting .Net Standard(as opposite to PCL that can install only ald packages)
Ability to edit csproj file on the fly without unloading project
Simplified csproj file
Cleaner look of dependencies
Smoother work (fewer bugs problems)
Some other stuff Im not aware of
Here is full list of changes.
For that you need to create new project from template .Net Standard->Class Library(.Net Standard). Than install all nuget packages there and link that project from your platform projects. Old PCL can be deleted. Here is some guide to migrate. Note: to install old nuget packages that targets .Net Portable you need to add in your csproj file similar lines:
<PropertyGroup>
<PackageTargetFallback>portable-net45+win8+wp8+wpa81</PackageTargetFallback>
<PackageTargetFallback>net461</PackageTargetFallback>
</PropertyGroup>
PackageTargetFallback attribute for every target framework you library needs. That will allow old packages to pass target checks.

Xamarin Forms - Targeting .NET Standard

I read this article a while ago:
https://blog.xamarin.com/net-standard-library-support-for-xamarin/
So, I converted all of our libraries from portable libraries to .NET Standard (1.4). I did this because the article says "This PCL now needs to be upgraded to target the .NET Standard Library, which can be found in the projects properties.".
However, I can't figure out how to build a Xamarin Forms project that targets .NET Standard. I cloned the Xamarin Forms samples, and opened up the MasterDetailPage project. I went in to the project properties and switched from portable to .NET Standard as per the instructions. Immediately, I get an error telling me that I need to opt in to NuGet 3.0 support. I'm fine with this, but how do I do it?
I found that if I remove the Xamarin Forms NuGet package, I am able to switch over to .NET Standard. However, once I have done this, I can't add the Xamarin Forms NuGet package back. It just keeps failing. Contrary to what the article says, I cannot add references to .NET Standard libraries. When I try to add a reference to existing .NET Standard libraries in my Solution, Visual Studio just gives me an error saying that the library is not compatible. Which version of .NET Standard should I be targeting for Xamarin Forms?
How do I get a .NET Standard library compiling with Xamarin Forms support?
If you wanna do it with the new Visual Studio 2017 release with csproj instead of project.json you can either use dotnet migrate CLI command or add/edit this code to your csproj file:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<PackageTargetFallback>$(PackageTargetFallback);portable-win+net45+wp8+win81+wpa8</PackageTargetFallback>
</PropertyGroup>
</Project>
It turns out that you can get a .NET Standard project to reference the Xamarin Forms NuGet package, and therefore be able to leverage .NET Standard libraries in Xamarin Forms.
This article more or less explains how to do it. The trick is to import the portable framework in the project.json.
https://xamarinhelp.com/dot-net-standard-pcl-xamarin-forms/
If you can't get it working, here is a Git sample that does work.
https://github.com/adamped/XamarinForms.NetStandard.git
I was eventually able to target .NET Standard 1.4 without issues.

Cross-targeting frameworks with NuGet 4.0 and Visual Studio 2017

I am having a rough time figuring out how to setup cross-targeting inside a Visual Studio 2017 project and I have not been able to find any examples.
I started out with a .NET Standard 1.5 project and to keep it simple I am just trying to add .NET Standard 1.6. If I understand the documentation correctly, I should now be able to do all of this inside the csproj file without having to mess with a project.json or nuspec file.
I've tried all of these values but none seem to work:
<TargetFrameworks>netstandard15;netstandard16</TargetFrameworks>
<TargetFrameworks>netstandard1.5;netstandard1.6</TargetFrameworks>
<TargetFrameworks>.NETStandard,Version=v1.5;.NETStandard,Version=v1.6</TargetFrameworks>
This is the only source of documentation I can find on the feature and it doesn't contain a full example:
https://docs.nuget.org/ndocs/schema/msbuild-targets
https://docs.nuget.org/ndocs/create-packages/supporting-multiple-target-frameworks
I've gotten this to work on latest Visual Studio 2017. As described in this post https://blogs.msdn.microsoft.com/dotnet/2016/10/19/net-core-tooling-in-visual-studio-15/ it is the correct way to do it. My csproj file looks like this:
<PropertyGroup>
<TargetFrameworks>netstandard1.6;net452</TargetFrameworks>
</PropertyGroup>
Visual Studio 2017 RC release notes also has this listed as a feature (under .NET Core and Docker):
Cross-target multiple target frameworks in one project.
My mistake at the start was that when I first created the project the property was called TargetFramework, I tried to add multiple targets and VS did not like that at all. It just crashes then... So make sure to rename it to TargetFrameworks and it should work.

Visual Studio 2015 target framework "dotnet" vs "net452"

When creating a new Visual Studio 2015 class library (package) project, one is able to set multiple target frameworks.
What is the difference between dotnet and net452?
project.json:
"frameworks": {
"dotnet": { },
"net452": {}
}
Project layout:
dotnet:
The new .NET Core for packages that don’t have any app model requirement, this is the runtime. (You could also use use dnx or dnxcore for example)
net452:
This need to be referenced if you want something that is only part of the full .net framework.
Oren Novotny has a great blog post explaining it.
I cannot answer to the previous answer from thllbrg (which is roughly right ... Also Oren blog post is the most important source at the current time), but one important clarification: dotnet does not have a runtime.
Libraries build with dotnet can deploy the DNX, .Net Framework and the UWP platforms (if the dependencies of your libraries allow so). All have different CLRs and compilation models. DNX e.g. support compilation on the fly, while UWP compiles ahead of time into one file and does tree shaking (the killing of not used functions in your library).

Resources