|
| 1 | +--- |
| 2 | +title: Select Assemblies Referenced By Projects |
| 3 | +description: Make a subset of assemblies in the package available to the compiler, while all assemblies are available at runtime. |
| 4 | +author: zivkan |
| 5 | +ms.author: zivkan |
| 6 | +ms.date: 05/24/2019 |
| 7 | +ms.topic: conceptual |
| 8 | +--- |
| 9 | + |
| 10 | +# Select Assemblies Referenced By Projects |
| 11 | + |
| 12 | +Explicit assembly references allows a subset of assemblies to be used for IntelliSense and compiling, while all assemblies are available at run-time. `PackageReference` and `packages.config` work differently, and as a result package authors need to take care to create the package to be compatible with both project types. |
| 13 | + |
| 14 | +> [!Note] |
| 15 | +> Explicit assembly references are related to .NET assemblies. It is not a method to distribute native assemblies that are P/Invoked by a managed assembly. |
| 16 | +
|
| 17 | +## `PackageReference` support |
| 18 | + |
| 19 | +When a project uses a package with `PackageReference` and the package contains a `ref\<tfm>\` directory, NuGet will classify those assembles as compile-time assets, while the `lib\<tfm>\` assemblies are classified as runtime assets. Assemblies in `ref\<tfm>\` are not used at runtime. This means it is necessary for any assembly in `ref\<tfm>\` to have a matching assembly in either `lib\<tfm>\` or a relevant `runtime\` directory, otherwise runtime errors will likely occur. Since assemblies in `ref\<tfm>\` are not used at runtime, they may be [metadata-only assemblies](https://github.com/dotnet/roslyn/blob/master/docs/features/refout.md) to reduce package size. |
| 20 | + |
| 21 | +> [!Important] |
| 22 | +> If a package contains the nuspec `<references>` element (used by `packages.config`, see below) and does not contain assemblies in `ref\<tfm>\`, NuGet will advertise the assemblies listed in the nuspec `<references>` element as both the compile and runtime assets. This means there will be runtime exceptions when the referenced assemblies need to load any other assembly in the `lib\<tfm>\` directory. |
| 23 | +
|
| 24 | +> [!Note] |
| 25 | +> If the package contains a `runtime\` directory, NuGet may not use the assets in the `lib\` directory. |
| 26 | +
|
| 27 | +## `packages.config` support |
| 28 | + |
| 29 | +Projects using `packages.config` to manage NuGet packages normally add references to all assemblies in the `lib\<tfm>\` directory. The `ref\` directory was added to support `PackageReference` and therefore isn't considered when using `packages.config`. To explicitly set which assemblies are referenced for projects using `packages.config`, the package must use the [`<references>` element in the nuspec file](../reference/nuspec.md#explicit-assembly-references). For example: |
| 30 | + |
| 31 | +```xml |
| 32 | +<references> |
| 33 | + <group targetFramework="net45"> |
| 34 | + <reference file="MyLibrary.dll" /> |
| 35 | + </group> |
| 36 | +</references> |
| 37 | +``` |
| 38 | + |
| 39 | +> [!Note] |
| 40 | +> `packages.config` project use a process called [ResolveAssemblyReference](https://github.com/Microsoft/msbuild/blob/master/documentation/wiki/ResolveAssemblyReference.md) to copy assemblies to the `bin\<configuration>\` output directory. Your project's assembly is copied, then the build system looks at the assembly manifest for referenced assemblies, then copies those assemblies and recursively repeats for all assemblies. This means that if any of the assemblies in your `lib\<tfm>\` directory are not listed in any other assembly's manifest as a dependency (if the assembly is loaded at runtime using `Assembly.Load`, MEF or another dependency injection framework), then it may not be copied to your project's `bin\<configuration>\` output directory despite being in `bin\<tfm>\`. |
| 41 | +
|
| 42 | +## Example |
| 43 | + |
| 44 | +My package will contain three assemblies, `MyLib.dll`, `MyHelpers.dll` and `MyUtilities.dll`, which are targeting the .NET Framework 4.7.2. `MyUtilities.dll` contains classes intended to be used only by the other two assemblies, so I don't want to make those classes available in IntelliSense or at compile time to projects using my package. My `nuspec` file needs to contain the following XML elements: |
| 45 | + |
| 46 | +```xml |
| 47 | +<references> |
| 48 | + <group targetFramework="net472"> |
| 49 | + <reference file="MyLib.dll" /> |
| 50 | + <reference file="MyHelpers.dll" /> |
| 51 | + </group> |
| 52 | +</references> |
| 53 | +``` |
| 54 | + |
| 55 | +and the files in the package will be: |
| 56 | + |
| 57 | +```text |
| 58 | +lib\net472\MyLib.dll |
| 59 | +lib\net472\MyHelpers.dll |
| 60 | +lib\net472\MyUtilities.dll |
| 61 | +ref\net472\MyLib.dll |
| 62 | +ref\net472\MyHelpers.dll |
| 63 | +``` |
0 commit comments