Skip to content

Instantly share code, notes, and snippets.

@dsplaisted
Created April 11, 2017 22:37
Show Gist options
  • Save dsplaisted/83d67bbcff9ec1d0aff1bea1bf4ad79a to your computer and use it in GitHub Desktop.
Save dsplaisted/83d67bbcff9ec1d0aff1bea1bf4ad79a to your computer and use it in GitHub Desktop.
Reference Assembly NuGet packages

Reference Assembly NuGet packages

Scenarios

  • Build a project which is multi-targeted to .NET Core or .NET Standard as well as .NET Framework on Mac OS or Linux using the .NET CLI
  • Build a project targeting Mono (which uses the same Target Framework Identifier as .NET Framework) using the .NET CLI

Design

  • There will be separate NuGet packages with reference assemblies for each version of .NET Framework. This means that projects targeting a single version of .NET Framework don't need to download and spend disk space on the reference assemblies and intellisense files for all the other possible versions of .NET Framework. It also means that when a new version of .NET Framework is released, the reference assemblies for the previous versions don't need to be re-shipped in an updated package along with the new assemblies.
  • There will be a single "metapackage" that can be referenced, that will have conditional dependencies on each of the version-specific reference assembly packages.
  • The metapackage will automatically be referenced by the .NET SDK when required (ie on non-Windows OS's). On Windows, we will probably make the .NET SDK continue to rely on the reference assemblies from the targeting packs by default.
  • For the package IDs, I suggest the following:
    • For the metapackage: Microsoft.NETFramework.ReferenceAssemblies
    • For the version-specific packages: Microsoft.NETFramework.ReferencesAssemblies.net462 (where net462 is replaced with the corresponding NuGet short framework Identifier)
  • The NuGet packages will include a .targets file that sets the TargetFrameworkRootPath to a path within the NuGet package. This will allow the existing MSBuild logic in the GetReferenceAssemblyPaths target and other logic such as automatically referencing the facades if necessary to continue to work as normal.
  • The logic in the .targets file in the NuGet packages will only set the TargetFrameworkRootPath if the TargetFrameworkIdentifier and TargetFrameworkVersion properties match the reference assemblies that the package provides. It will also only set the property if the UseReferenceAssembliesFromPackage property is set to true.
  • The reference assembly packages should include the .xml intellisense documentation files. I believe the .xml documentation files have to be in the same folder as the reference assemblies, so there isn't a way to deliver them as a separate package.
  • If we want to support localized intellisense, we would need to create a separate set of packages and corresponding meta-package for each language supported. The IDs of these packages could follow the pattern Microsoft.NETFramework.ReferenceAssemblies.pt-br. The SDK could use a property to select which language's metapackage to reference.
  • The reference assembly packages should not show up as dependencies of "normal" packages. Thus, the reference assembly packages should set developmentDependency to true in it's metadata. Likewise, when the .NET SDK automatically references the reference assembly metapackage, it should use PrivateAssets="All".
  • The reference assembly packages should include the same layout of files that are installed by the targeting packs under C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework. This should be rooted at the path specified by the TargetFrameworkRootPath property in the package. For example, if the .targets file, which is in the build folder of the NuGet package, sets the TargetFrameworkRootPath to $(MSBuildThisFileDirectory), then the .NET 4.6.2 reference assembly package should have the reference assemblies and intellisense files in the build\.NETFramework\v4.6.2 folder, as well as have the Facades, PermissionSets, and RedistList folders with corresponding files under that folder.
  • The version number of each package should start at 1.0.0. When a new version of the .NET Framework is released, a corresponding reference assembly package (versioned at 1.0.0) should be released, and a new metapackage that includes the additional dependency for the newly supported version should be released. The new version of the metapackage should have it's minor version incremented. If we need to fix an issue with the packages, we can ship new versions with the patch version incremented, and a new metapackage with dependencies on the patched packages.
  • We need to determine what license to use for these packages.
  • We will also need to determine the details of the package metadata, such as the description, project URL, icon, etc.

Proof of concept package production

A proof of concept that produces these packages from the reference assemblies installed from the targeting packs on a machine can be found here: https://github.com/dsplaisted/ReferenceAssemblyPackages

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment