wpf/Documentation/gen-api.md

3.9 KiB

GenApi Usage in WPF on .NET Core

In WPF on .NET Core, C# reference assemblies are created via the use of GenAPI and a separate reference assembly project located in the ref directory under a particular assemblies source directory.

WPF assemblies make extensive use of the InternalsVisibleToAttribute which precludes the use of ProduceReferenceAssembly or ProduceOnlyReferenceAssembly. This is because these compiler options will include internal types and members in the reference assembly. In WPF, this creates dangling references to assemblies that do not exist in the WindowsDesktop reference pack.

Using GenAPI allows us to strip out internals, removing the dangling references from our reference assemblies.

GenApi.props

Contains various properties related to GenAPI runs and configurations.

  • GenAPIEnabledProjects
    • The set of projects to run GenAPI on
  • GlobalApiExclusionsFile
  • GlobalAttrExclusionsFile
  • GenAPIAdditionalParameters
    • Parameters to GenAPI built up from local configuration
  • _GenerateReferenceAssemblySource
    • A private parameter used to enable GenAPI targets

GenApi.targets

Contains targets and properties related to GenAPI runs

  • GenAPITargetDir
    • The directory where GenAPI will generate code
  • GenAPITargetPath
    • The full path to the file GenAPI will generate
  • EnsureGenAPITargetDirectory
    • Creates the directory specified by GenAPITargetDir if it does not exist

Using GenAPI in WPF

GenAPI is run only on-demand. In the event that a change to a runtime assembly creates new public surface area, a developer will see an ApiCompat error between the reference assembly and the runtime assembly. In order to address this, the developer must run GenAPI to generate new reference assembly code.

Running GenAPI

GenAPI can be run by setting the following MSBuild property while building.

/p:GenerateReferenceAssemblySource=true

When a build is run with that property enabled, GenAPI will read the runtime assembly and generate a new {AssemblyName}.cs file under the ref directory in the assembly's source tree.

This new file will contain the newly created surface area and will need to be checked in along with the runtime assembly change. The next build without GenerateReferenceAssemblySource enabled will no longer display an ApiCompat error as the surface area will now match the baseline.

Workflow for GenAPI

GenAPI generates a lot of code that is either private, internal, or causes build errors. For this reason a developer usually cannot just use the output of GenAPI directly. Instead, the developer should do the following:

  • Build with GenAPI enabled
  • Diff the output file against the previous version
  • Extract just the new surface area and related code from the generated code (this is typically a very small fraction of the diff)
  • Restore the generated file
  • Add back the new surface area to the reference assembly code
  • Ensure that nothing in the new surface area is private or internal unless requried by XAML compilation or other reference assemblies
  • Restore all other files GenAPI may have generated
  • Rebuild without GenAPI enabled and verify there are no ApiCompat errors