Namespace settings:
- Except for the “XamUtils.Abstractions” project, the default namespace for all the other projects (the platform-specific implementation projects) should be changed to “XamUtils”
- The default namespace in the platform-specific libraries would normally be something like “XamUtils.iOS”, but these all need to be changed to the one single namespace
- Setting the namespace and output assembly name for all the platform-specific implementation projects to the same as the namespace and assembly name as the PCL “Stub” project is what allows the “bait-and-switch” approach to use the platform-specific libraries at runtime instead of the PCL library that was used at design-time.
Assembly Name settings:
- As with the Namespace setting above, except for the “XamUtils.Abstractions” project, the “Output -> Assembly Name” for all the other projects should be “XamUtils” (rather than their default values such as “XamUtils.iOS”).
Assembly Values:
- Create a “GlobalAssemblyInfo.cs” file in the “XamUtils.Shared” project and move most of the assembly information to this file, removing most of it from the AssemblyInfo.cs files in each individual project.
- Just leave “AssemblyTitle” and “AssemblyProduct” in the individual AssemblyInfo.cs files, plus anything else specific to that platform such as Android permissions
Constants to be Defined:
- In the PCL project, define a “PORTABLE” constant (in both the DEBUG and RELEASE configurations). This constant can be used by code in the Shared project to selectively remove implementation code that is not available in the selected PCL profile while still leaving the method signatures in place.
Code Locations:
- Shared code should be put in the Shared Project (“XamUtils.Shared”).
- Code that requires platform-specific implementations should be put in the platform-specific libraries, with matching “stub implementations” of the classes and methods being put in the PCL project.
- The stub implementations in the PCL project should throw a NotImplementedException in case the PCL library is accidentally included in a project rather than the platform-specific library.
To Add a New Class:
- For a class containing shared code:
- Add the class file to the Shared project
- For a class containing code for only one specific platform:
- Add the class file to the project for that platform
To Add a New Method to an Existing Class:
- If no platform-specific implementation is required:
- Add the code to the Shared project
- If platform-specific implementation is required:
- Add the implementation code to each platform-specific project
- Add a stub method with the same signature to the PCL project
- If a platform-specific method is needed where a shared class already exists (to provide additional functionality for one platform that does not exist on the other platforms):
- Change the definition of the existing shared class to be a partial class
- Create a new partial class in the platform-specific library that has the same name as the class in the shared project
- Add the implementation of the platform-specific method in the new partial class you just added to the platform-specific project.
File naming conventions:
- xxx.cs – Shared code class files (code without any stubs or platform-specific implementation)
- e.g.: DateUtils.cs – Contains date-related utilities that are common across all platforms
- xxx_stubs.cs – Class files in the PCL project that contain only “stub” methods
- e.g.: Log_stubs.cs – Contains the empty stub methods for the logging methods
- Note that although the file is named “xxx_stubs”, the class name does not include the “_stubs” suffix.
- xxx_impl.cs – Class files in the platform-specific projects that contain the actual method implementations that correspond to the xxx_stubs.cs class files
- e.g.: Log_impl.cs – Classes in the iOS and Android projects that implement the actual logging methods
- Note that as with the “xxx_stubs.cs” file, although the file is named “xxx_impl”, the class name does not include the “_impl” suffix.
- xxx_{platformCode}.cs – Contains platform-specific code that is only available on a specific platform, and where there is no corresponding shared or PCL stub code
- e.g.: DateUtils_iOS.cs – Contains the additional iOS-specific date-related methods such as “DateTimeToNSDate”
- Note that the class name does NOT include the “_{platformCode}” suffix.