Skip to content

Commit 9a60262

Browse files
authored
Merge pull request NuGet#1443 from NuGet/zivkan-reference-assemblies
Add info on how to make reference assemblies compatible with PR
2 parents 53ae0ff + 7cea798 commit 9a60262

File tree

3 files changed

+65
-5
lines changed

3 files changed

+65
-5
lines changed

docs/TOC.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
## Advanced tasks
4040
### [Modify source code and config files](create-packages/source-and-config-file-transformations.md)
4141
### [Create a localized package](create-packages/creating-localized-packages.md)
42+
### [Select assemblies referenced by projects](create-packages/select-assemblies-referenced-by-projects.md)
4243
## Guides for specific content
4344
### [Create a UWP package](guides/create-uwp-packages.md)
4445
### [Create a native package](create-packages/native-packages.md)
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
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+
```

docs/reference/nuspec.md

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ The following example shows different variations of the `<group>` element:
298298

299299
## Explicit assembly references
300300

301-
The `<references>` element explicitly specifies the assemblies that the target project should reference when using the package. When this element is present, NuGet add references to only the listed assemblies; it does not add references for any other assemblies in the package's `lib` folder.
301+
The `<references>` element is used by projects using `packages.config` to explicitly specify the assemblies that the target project should reference when using the package. Explicit references are typically used for design-time only assemblies. For more information, see the page on [selecting assemblies referenced by projects](../create-packages/select-assemblies-referenced-by-projects.md) for more information.
302302

303303
For example, the following `<references>` element instructs NuGet to add references to only `xunit.dll` and `xunit.extensions.dll` even if there are additional assemblies in the package:
304304

@@ -309,10 +309,6 @@ For example, the following `<references>` element instructs NuGet to add referen
309309
</references>
310310
```
311311

312-
Explicit references are typically used for design-time only assemblies. When using [Code Contracts](/dotnet/framework/debug-trace-profile/code-contracts), for example, contract assemblies need to be next to the runtime assemblies that they augment so that Visual Studio can find them, but the contract assemblies need not be referenced by the project or copied into the project's `bin` folder.
313-
314-
Similarly, explicit references can be used for unit test frameworks, such as XUnit, which needs its tools assemblies located next to the runtime assemblies, but does not need them included as project references.
315-
316312
### Reference groups
317313

318314
As an alternative to a single flat list, references can be specified according to the framework profile of the target project using `<group>` elements within `<references>`.

0 commit comments

Comments
 (0)