Reusing code can be a great way to increase efficiency within an organization. If there is an overlap in functionality across multiple development projects it makes sense to collaborate and reuse code across those projects.
An essential tool for any collaborative development environment is a mechanism through which developers can create, share, and consume code. Often such code is bundled into “packages” that contain compiled code (as DLLs) along with other content needed in the projects that consume these packages. Using packages to transmit code facilitates the natural process of integrating updates that improve and add to functionality available to collaborators.
NuGet is a free and open-source package manager designed for the Microsoft development platform. Since its introduction in 2010, NuGet has evolved into a larger ecosystem of tools and services. NuGet is distributed as a Visual Studio extension. Beginning with Visual Studio 2012 and subsequent versions, NuGet is pre-installed with Visual Studio by default. NuGet can also be used from the command line and automated with scripts. NuGet is the standard tool by which package dependencies are managed in Visual Studio projects/solutions.
A NuGet package is a single ZIP file with the .nupkg extension that contains:
- Compiled code (DLLs)
- Other support files related to that code
- Descriptive manifest that can include:
- Package ID
- Package Version Number
- Package Author Info
- Package Description
- Other Fields Included: Owner Info, Copyright, Title, Summary, Project URL, Icon URL, License URL, Tags, Release Notes
Creating A Single Cross-Platform NuGet Package For Xamarin Mobile Application Development
Visual Studio library projects can be configured to create a variety of packages with differing levels of compatibility from a single platform to multiple platforms. Most of the time creating NuGet packages with Visual Studio is simple and works well, but I encountered a few build errors while attempting to build a single multi-platform NuGet package for Xamarin mobile application projects using Visual Studio for Mac (VS for Mac). Here are a couple examples:
- The Target “GetPackageContents GetPackageTargetPath” does not exist in the project. (MSB4057)
- The “AssignPackagePath” has failed unexpectedly. (MSB4018)
Below is a step-by-step process for VS for Mac to create a cross-platform NuGet package that will run on iOS and Android that leverages Xamarin.Forms. Following this outlined process helps to mitigate and avoid some errors, but even this process is not error proof. It may take a few tries to produce an error-free cross-platform NuGet package with VS for Mac.
- Open Visual Studio and click File, and then choose New Solution.
- For your project template Select Multiplatform Library (as shown below).
- Next configure the solution. Give it a name and a brief description. Select Android and iOS under Target Platforms, then under Implementation select Single for all platforms.
- Make sure the project name, solution name, and path are the way you want it, then click Create.
- To add platform-specific references the next step is to right-click on the project and under Add click Add Platform Implementation.
- Select Android, iOS, and Create Shared Project as shown below.
- When this process completes you should Build All in order to confirm that your solution is error free. Sometimes the build will fail at this point. This seems to be an expression of an error inherent in the processes executed by the VS for Mac IDE. If Build All fails it may be best to simply start over.
- Now is the time to make sure that the References in all the projects are correct. The main project should reference the .Shared project. The .iOS and .Android projects should have references to the main project and Xamarin.iOS or Xamarin.Android respectively. The .NuGet project should reference the main and .Shared projects.
- The next step is to add the Xamarin.Forms package to the .Android, .iOS, .NuGet and main projects.
- For proof of concept add a Xamarin Forms Page in the .Shared project with a label that says “Hello World.”
- Right-click on the main project and then select Options. In the Build section under General confirm that Target Framework is set to .Net Portable with a PCL profile that is compatible with the platforms to which you want to deploy your package. In our case, Profile 111 is correct.
- While in Project Options, under the NuGet Package click on MetaData to add or edit the data that will be associated with the package you create.
- Under the NuGet Package section Build tab, select “Create a NuGet Package when building the project.”
- Now when you Build All the single, multiplatform package will be generated and saved in the main project’s /bin/ folder (either Debug or Release, depending on configuration). The NuGet package file will be saved with the extension .nupkg
With a little luck at the end of this process you should now have a single NuGet package that will deploy to both Android and iOS with the ability to leverage Xamarin.Forms.
NuGet Package Distribution
NuGet packages can be distributed and consumed in multiple ways. If your package is meant to be shareware it can be published and distributed for public consumption directly on nuget.org. If the packages are meant to be proprietary then a private repository can be created. Something as simple as a folder on a secured network will work. The NuGet Package Manager in VS can then be configured to load or update packages from whatever location your packages are stored. The location can be configured by opening the VS project you want to add the package to and then complete the following steps:
- If Loading New Package:
- Right click on “Packages” folder in the target Project and select Add Package
- Select Configure Source and add local directory in which NuGet Package resides.
- Set the Package Manager source to the folder that was added
- Select the Package to be installed
- Click Add Package (if it is a Shared Project Solution the package will need to be added to each each Project)
- If Updating Package:
- Right click on the package to be updated and click Update (updated package should be located in local directory the package was originally loaded from) (if it is a Shared Project Solution the package will need to be updated in each each Project)
The Value of NuGet
Leveraging the power of NuGet is an excellent way to package, transmit, consume, and update shared code across .NET projects. As the default package manager for Visual Studio it is familiar to developers and already integrated into the IDE’s workflow. The example package described here is one of the more complex scenarios, but generally speaking it is relatively simple to create platform specific packages. The distribution and update process are also easy to implement and manage. All of this adds up to saving time and money for your enterprise.
If you would like to do some additional reading I have listed below a partial list of resources I used to create this article.
Manually Creating NuGet Packages for Xamarin
Cross-Platform Development with the Portable Class Library
Creating a New Multiplatform Library for NuGet
Create .NET Apps Faster With Nuget
An Introduction to NuGet
Portable Class Libraries (PCL)