Thursday, 29 October 2020

Ways can we share the code - Sharing code overview

 There are three ways we can share code:

  • Shared Project: Here, if required, we write platform specific code using #if compiler directives.
  • Portable Class Libraries:((deprecated - ) Here, we create a PCL targeting the platforms we wish to support and then we use Interfaces & Dependency Services to use platform specific functionality.Use the Shared Asset Project type to organize your source code, and use #if compiler directives as required to manage platform-specific requirements.
  • .NET Standard Libraries: It works similar to the PCL and requires Interfaces to work with platform specific functionality. .NET Standard projects can implement code to be shared across multiple platforms, and can access a large number of .NET APIs (depending on the version). .NET Standard 1.0 - 1.6 implement progressively larger sets of APIs, while .NET Standard 2.0 provides the best coverage of the .NET BCL (including the .NET APIs available in Xamarin apps).

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.

namespace Chat

    {


         public partial class App : Xamarin.Forms.Application

            {

        #if __IOS__

                public App()

                {

        #else

                public App(Intent screenshareIntent)

                {

        #endif

                    InitializeComponent();

        #if __IOS__

                    MainPage = new NavigationPage(new SessionSelector());

        #else

                    MainPage = new NavigationPage(new SessionSelector(screenshareIntent));

        #endif

                    AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

      }


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.

Benefits

  • Allows you to share code across multiple projects.
  • Shared code can be branched based on the platform using compiler directives (eg. using #if __ANDROID__ , as discussed in the Building Cross Platform Applications document).
  • Application projects can include platform-specific references that the shared code can utilize (such as using Community.CsharpSqlite.WP7 in the Tasky sample for Windows Phone).

Disadvantages

  • Refactorings that affect code inside 'inactive' compiler directives will not update the code inside those directives.
  • Unlike most other project types, a Shared Project has no 'output' assembly. During compilation, the files are treated as part of the referencing project and compiled into that assembly. If you wish to share your code as a assembly then .NET Standard or Portable Class Libraries are a better solution.

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.

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.

Benefits

  • Allows you to share code across multiple projects.
  • Refactoring operations always update all affected references.
  • A larger surface area of the .NET Base Class Library (BCL) is available than PCL profiles. In particular, .NET Standard 2.0 has almost the same API surface as the .NET Framework and is recommended for new apps and porting existing PCLs.

Disadvantages

  • Cannot use compiler directives like #if __IOS__.

PCL Vs Shared

  • PCL has an output assembly as DLL while Shared Project has no output assembly.
  • Files inside PCL are treated as part of PCL while in Shared Project, files are treated as part of the referencing project and compiled into that assembly.
  • PCL contains neat and clean platform independent code while Shared Project consists of many #if compiler directives to differentiate code among platforms.
  • PCL is the best approach if good project architecture is the main concern instead of Shared Project.
  • PCL uses the Interfaces and DependencyServices to access platform specific features while Shared Project can assess them directly.
  • PCL has less compile time errors while Shared Project has many chances of compile time errors while switching among platform specific projects.
  • PCL is used if less platform specific code is required. Shared Project is used when lot of platform specific code is required. However, this is not true all the time. Choice is always on the developer.


The most important characteristics of .NET Standard libraries are:

  • They produce a compiled, reusable .dll assembly.
  • They can reference other libraries and have dependencies such as NuGet packages.
  • They can contain XAML files for the user interface definition and C# files.
  • They cannot expose code that leverages specific APIs that are not available on all the platforms targeted by a specific .NET Standard version.
  • They are a better choice when you need to implement architectural patterns such as MVVM, factory, inversion of control (IoC) with dependency injection, and service locator.
  • With regard to Xamarin.Forms, they can use the service locator pattern to implement an abstraction and to invoke platform-specific APIs through platform projects.
  • They are easier to unit test.

PCL it will become obsolete now. .NET Standard is the evolvement of the PCL libraries.

With PCL libraries you could target a number of platforms and only the functionality that was supported for all targeted platforms were available to you. Associated with each combination of platforms were the profiles. A profile was identified by two or three digits. Notable ones for Xamarin were 111 or 259. Read more on PCLs here: https://docs.microsoft.com/en-us/xamarin/cross-platform/app-fundamentals/pcl

.NET Standard is a specification of the APIs associated to it. If a platform supports a certain version of the .NET Standard, you are guaranteed that all APIs are available. This way, you can simply target a specific .NET Standard version and each platform that supports it will support your application. The .NET Standard specification has gained a lot of traction and is already more cross-platform than a PCL ever was. Most of the creators of NuGet packages are supporting it already and also Xamarin/Microsoft has replaced the PCL with a .NET Standard library in their templates. Read more on .NET Standard as a concept here: https://docs.microsoft.com/en-us/dotnet/standard/net-standard

So, if you have the possibility it might be wise to start moving to the .NET Standard library. That is, if you want to keep supporting your app and need new libraries coming in. If your app is fine the way it is, you can probably keep going with the PCL for a while. Converting is basically: change the csproj structure to the new structure. Retarget your library to netstandard and reinstall all the libraries you have installed, this time to download the .NET Standard compatible version. The last step might be a bit of a pain.

Coverting PCL to .NetStandard. https://smellyc0de.wordpress.com/2018/03/23/automatically-converting-pcl-to-net-standard-2-0-project/

No comments:

Post a Comment

All About .NET MAUI

  What’s .NET MAUI? .NET MAUI (.NET Multi-platform App UI) is a framework for building modern, multi-platform, natively compiled iOS, Androi...

Ads2