Updated: 7th Aug 2017
In Xamarin Forms I see a lot of examples using Shared Projects and hence lots of new comers to Xamarin base their first apps off these examples. Besides legacy use cases, there very limited reasons to use SharedProjects in Xamarin Forms applications, PCL’s (Portable Class Libraries) or SCL’s (.NET Standard Class Libraries) are the preferred method in most scenarios.
Using Shared Projects
Shared Projects are the default when creating a Windows Store or UWP app so you can write the same code for Windows Store and the Phone. I still think Microsoft was not quite right to set this as default but at least the code will most likely be so similar there would not be much difference between them and hence fewer compiler directives.
With a SharedProject you now create classes as per usual but if you want to do something platform specific you implement a compiler directive around the code. You may implement partial classes but those ifdefs can sneak in.
I can agree that partial classes for Shared Projects can be a nice solution in a small project. However if you have multiple developers or anything more than a really simple app or demo project, maintainability of a Shared Project becomes less than pleasant due to lack of architectural control and struggling to find what is actually running on each platform.
Next a Shared Project suffers from issues when defining an assembly name. For example in xaml if you wanted to reference a control and reference an assembly name, each native project will have a different assembly name, so you either have to do some more ifdefs or OnPlatforms, or have to name each native project the same assembly name.
Using .NET Standard Class Libraries (SCL)
Note: You may have previously heard of PCL’s, however with .NET Standard, it is now recommended to use .NET Standard Class Libraries, SCL’s.
SCL’s don’t come without some of their own headaches but they provide a great way to write code once, that can be used on multiple platforms, easily maintained and tested. When you write an SCL you don’t need to insert compiler directives to switch code depending on each platform, you select which platforms you will support by choosing which standard version to support.
Once you have a .NET Standard Library, you can change which version it supports by going into properties and selecting the appropriate version.
Which version you choose, depends upon which platform you want to support. For Xamarin apps that need to support Android, iOS and UWP, I choose .NET Standard 1.3. You can find out more information in Microsoft’s .NET Standard documentation.
Portable Class Libraries (Obsolete)
If for some reason you still use a Portable Class Library, here is a quick overview.
When you create a PCL, you can go to the Properties and set the Targets for the project.
For Xamarin Forms projects, it is best to use this common setup. It allows you to target all 3 platforms.
PCL’s are projects that can target different platforms, you can choose which ones and then it gives you access to certain assemblies and functions depending on which ones you select. The different combinations targets for PCL’s are referred to as Profiles and each Profile has its own number. The most common and recommended profile for Xamarin Forms projects is Profile259. If you edit the *.proj file of your PCL project with the above targets you will see this profile number.
Lets say that you write SCL’s but you now need to implement something platform specific. You do this by writing the platform specific code within the native project (or a native class library).
In a common SCL, create an Interface that both your native platform and SCL use. Use dependency injection to inject that class into your project and now you have access to the platform specific code from any SCL referenced by both projects.
If you are not familar with Dependency Injection, please have a look at Xamarin Forms Dependency Injection, for an introduction.
There are some great benefits for using SCL’s
- Easier unit testing
- Easier to read code
- Greater Portability
- Cleaner implementation of code
Profile Based PCL vs .NET Standard Class Library (SCL)
Profile Based PCL’s as I mentioned above have now been superseded by .NET Standard Class Libraries. These libraries remove a lot of issues with Profile Based PCL’s and many package providers are upgrading to support only .NET Standard Libraries. Have a look at .NET Standard Libraries with Xamarin Forms if you want to learn more.
Which To Use?
Portable Libraries (.NET Standard or Profile Based) are the preferred method by every Xamarin developer I have met or spoke to about it online, or I quickly convince them otherwise. Shared Projects have their use but its limited and normally for backward compatibility reasons, small apps or prototyping.
If you develop in a SCL, you know that the code you are developing is cross-platform. It forces you to ensure everything you write is cross-platform and increases test-ability. To me, shared projects open you to developing code or business logic, heavily mixed in with platform specific code, which only leads to maintenance issues.