With the recent release of Visual Studio 2017 v15.3 (and subsequent patch release 15.3.1 and 15.3.2…. yes, it does say something about ship quality ) came the release and support for .NET Standard 2.0. The Xamarin team also made a lot of noise about support for .NET Standard 2.0; unfortunately this doesn’t yet translate into Visual Studio templates that easily get you started. My particular annoyance is the about of steps you need to go through in order to just spin up a new Xamarin Forms application that can reference .NET Standard libraries. I thought I’d piggyback of a post done a couple of months back by Pierce Boggan. Here goes:
Start by creating a new project in Visual Studio 2017, selecting the Cross Platform App (Xamarin) project template:
Next, select the template you want (I’m going with the Blank App), the UI Technology and Code Sharing Strategy. As I’m going to be walking through how to use Xamarin Forms, it makes sense to pick that as the option for UI Technology. Only select the Portable Class Library option. Don’t use the Shared Project – using a shared project will lead you down the evil road of using conditional compilation which will be a maintenance nightmare, just don’t use it. I don’t care how great you think it is, don’t use it. One last time, don’t use the Shared Project option.
Now that I’ve expressed my opinion on code sharing strategies, let’s click the OK button and get on with building our application. As the template goes through generating the head projects for iOS, Android and UWP, it will prompt you to select the target and minimum platforms for UWP. For the most part, unless you have specific target platform requirements for UWP, you can leave the default settings.
The generated solution will have four projects: three head or target platform projects (for iOS, Android and UWP) and a portable class library (PCL) which contains the XAML pages that will make up your Xamarin Forms application layout. In order to proceed with .NET Standard support we need to replace the PCL with a .NET Standard library. Whilst Visual Studio used to have a mechanism for upgrading a library from a PCL to a .NET Standard library, this has been removed. Now the easiest way is to simply create a new project, and copy the relevant files into the new project. From the Add New Project dialog, select the Class Library (.NET Standard) template.
I use the .UI naming convention for the library that will contain my XAML pages. Other developers use .Core but my preference is to separate my XAML pages away from my view models. Whilst technically with Xamarin Forms they can reside in the same library, I prefer to have a clean separation between them. I have <applicationname>.UI with my XAML pages in it and <applicationname>.Core with my view models, services, entities, essentially all the business logic for my application.
For this example I’m going to keep it simple and we’ll just create the .UI project for the moment.
I don’t need the default Class1.cs, so I’ll remove that. I’ll add a reference to the .NET Standard library to all the head projects.
I’m also going to drop the .NET Standard version back from 2.0 (now the default in Visual Studio) back to 1.4. Whilst the tooling has been updated for the head projects for iOS and Android to support .NET Standard 2.0, of course, UWP is still lagging the field, as so you won’t be able to use a .NET Standard 2.0 library until that’s fixed. To be honest though, not much is lost by lowering the version of the .UI project to 1.4 since all the features of Xamarin Forms are still there.
Next I’m going to copy App.xaml (and App.xaml.cs) and MainPage.xaml (and MainPage.xaml.cs) from the PCL into the newly created .NET Standard library. Once I’ve copied these files across I can remove the PCL project from the solution – this will remove the references to this library from each of the head projects. After coping these files across, you may well see a compilation error similar to the following:
1>------ Build started: Project: MyFirstXamarinFormsApp.UI, Configuration: Debug Any CPU ------
1>C:\Program Files\dotnet\sdk\2.0.0\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.Sdk.DefaultItems.targets(274,5): error : Duplicate 'EmbeddedResource' items were included. The .NET SDK includes 'EmbeddedResource' items from your project directory by default. You can either remove these items from your project file, or set the 'EnableDefaultEmbeddedResourceItems' property to 'false' if you want to explicitly include them in your project file. For more information, see https://aka.ms/sdkimplicititems. The duplicate items were: 'App.xaml'; 'MainPage.xaml'
1>Done building project "MyFirstXamarinFormsApp.UI.csproj" -- FAILED.
If you do, you just need to edit the project file for the .UI project and remove the App.Xaml and MainPage.xaml EmbeddedResource elements. The new project format includes files by default and the tooling isn’t smart enough to realise that the sample files are being added multiple times. Removing these elements will fix the compilation:
The last thing to do is to make sure that the .NET Standard library references Xamarin Forms. I’m going to do that by right-clicking the solution node in Solution Explorer and selecting Manage Nuget Package for Solution.
I’m going to select the new prerelease version of Xamarin Forms (which is the one where they’ve apparently added .NET Standard support). In addition to adding a reference to Xamarin Forms to the UI project, I also take this opportunity to upgrade all the package references in the application. Note that I’ve even selected the Android support packages – this used to be a big No-No but with the latest version of the tooling you can now go ahead and update them, and I would definitely encourage you to do so.
Now, go make yourself a coffee – Nuget is slow, so slow! The good news is that once you’ve done all these steps, you’re ready to go with a .NET Standard based Xamarin Forms project. If you’re following this post to get started on your own project, you can finish up here, as you’re good to go.
Ok, so all of that, and what can we do. We’ll for a starters, it makes it super easy to add nuget packages such as BuildIt Forms which has a bunch of helper controls and features to get you building richer applications. Let’s add a reference to the BuildIt.Forms Nuget package the project:
After adding the reference to BuildIt.Forms we can make use the added controls. For example the ContentButton allows us to easily add a button that contains any XAML content, whilst still maintaining the pressed and hover states:
<?xml version="1.0" encoding="utf-8" ?>
<Label Text="Welcome to Xamarin Forms!" />
<Label Text="Press m!" />
I’ll cover more on the BuildIt.Forms library in coming posts.