Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to package a .NET library that targets the Universal Windows Platform and depends on Visual Studio extension SDKs?

How do I package a Universal Windows Platform library that depends on Visual Studio extension SDKs such as the Microsoft Player Framework?

Specifically, I want users of my library to be able to use it immediately after pressing the Install button in NuGet, without having to manually add the extension SDKs to their projects. Assuming, of course, that the appropriate extension SDKs are actually installed.

This is a series of questions and answers that document my findings on the topic of modern NuGet package authoring, focusing especially on the changes introduced with NuGet 3. You may also be interested in some related questions:

  • How to package a .NET Framework library?
  • How to package a .NET library targeting the Universal Windows Platform?
  • How to package a portable .NET library targeting .NET Core?
  • How to package a .NET library targeting .NET Framework and Universal Windows Platform and include platform-specific functionality?
  • How to package a multi-architecture .NET library that targets the Universal Windows Platform?
like image 316
Sander Avatar asked Jan 05 '16 12:01

Sander


1 Answers

This answer builds upon the principles of .NET Framework library packaging and the principles of Universal Windows Platform library packaging. Read the linked answers first to better understand the following.

When you directly reference a Visual Studio extension SDK in a project, the following snippet is included in the .csproj file:

<SDKReference Include="Microsoft.PlayerFramework.Xaml.UWP, Version=3.0.0.2">
  <Name>Microsoft Player Framework</Name>
</SDKReference>

NuGet offers functionality that enables an equivalent action to be performed when installing a NuGet package. The first thing you must do is to create in your project a .targets file (e.g. MyLibraryUsingExtensionSdk.targets) that contains the relevant XML to be added to the project into which your library is installed. You will want to copy the relevant <SDKReference> element from your library's .csproj file and also include any parent elements, creating a full XML document that can be merged.

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <ItemGroup>
        <SDKReference Include="Microsoft.PlayerFramework.Xaml.UWP, Version=3.0.0.2">
            <Name>Microsoft Player Framework</Name>
        </SDKReference>
    </ItemGroup>
</Project>

Set the build action of this file to None, to avoid it being needlessly touched by the build process.

By including this .targets file in the appropriate location in the NuGet package structure, it will be automatically merged at runtime into projects that make use of your library. You want to achieve the following package structure:

+---build
|   \---uap10.0
|           MyLibraryUsingExtensionSdk.targets
|
\---lib
    \---uap10.0
        |   MyLibraryUsingExtensionSdk.dll
        |   MyLibraryUsingExtensionSdk.pdb
        |   MyLibraryUsingExtensionSdk.pri
        |   MyLibraryUsingExtensionSdk.XML
        |
        \---MyLibraryUsingExtensionSdk
                ExampleControl.xaml
                MyLibraryUsingExtensionSdk.xr.xml

You can create such a package using the following .nuspec template:

<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
    <metadata minClientVersion="3.2">
        <id>Example.MyLibraryUsingExtensionSdk</id>
        <version>1.0.0</version>
        <authors>Firstname Lastname</authors>
        <description>Example of a simple UWP library that depends on an extension SDK.</description>
    </metadata>
    <files>
        <!-- Causes referencing this NuGet package to also automatically reference the relevant extension SDKs. -->
        <file src="MyLibraryUsingExtensionSdk.targets" target="build\uap10.0\MyLibraryUsingExtensionSdk.targets" />

        <file src="..\bin\Release\MyLibraryUsingExtensionSdk**" target="lib\uap10.0" />
    </files>
</package>

Note that Visual Studio will require a solution reload to fully recognize the extension SDK after installing such a NuGet package. Builds will work immediately without problems but IntelliSense will not pick up the new extension SDK until a reload.

Unfortunately, this approach does require you to hardcode the version number of the extension SDK, which can be problematic. At the moment of writing, I know of no way to specify a range of versions or a version-independent reference.

Remember to build your solution using the Release configuration before creating the NuGet package.

A sample library and the relevant packaging files are available on GitHub. The solution corresponding to this answer is UwpLibraryDependingOnExtensionSdks.

like image 103
Sander Avatar answered Oct 25 '22 04:10

Sander