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 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. S
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 Portable Class Libraries (PCL)
PCLs don’t come without their own set of 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 a PCL you don’t need to insert compiler directives to switch code depending on each platform, you select which platforms you will support then starting coding.
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 PCL’s but you now need to implement something very platform specific. You do this by writing the platform specific code within the native project (or a native class library). In a common PCL, create an Interface that both your native platform projects depend on.
Use dependency injection to inject that class into your project and now you have access to the platform specific code from any PCL referenced by both projects.
To use Depending Injection Xamarin have a great Introduction to get started with their in-built dependency service that is included out of the box with Xamarin Forms: https://developer.xamarin.com/guides/xamarin-forms/dependency-service/
There are some great benefits for using PCL’s
- Easier unit testing
- Easier to read code
- Greater Portability
- Better implementations of code
Profile Based PCL vs .NET Standard Library
Profile Based PCL’s as I mentioned above have now been superseded by .NET Standard 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 PCL, 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.
If you disagree with me, I am open to intense debate. Feel free to email, or post on the Xamarin Forums Why Shared Projects? and tag me in 🙂