Skip to content

Commit 4a909b7

Browse files
committed
Create explicit assembly reference page
1 parent dd0b141 commit 4a909b7

File tree

2 files changed

+64
-10
lines changed

2 files changed

+64
-10
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
---
2+
title: Explicit Assmbly References
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+
# Explicit Assembly References
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. Projects that use `packages.config` work differently to projects that use `PackageReference` and as a result, package authors need to take care to create the package to be compatible with both types of usage.
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 advertise those assembles as compile-time assets, while the `lib\<tfm>\` assemblies are advertised 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 optionally 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 use NuGet packages normally add references to all assemblies in the `lib\<tfm>\` directory. The `ref\` directory was a new feature for `PackageReference` and therefore isn't considered when using `packages.config`. In order 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+
> The details of how assemblies are copied to the `bin\<configuration>\` directory is though a process called ???. 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 if your `lib\<tfm>` directory contains 3 assemblies, `a.dll`, `b.dll`, and `c.dll` and you specify `a.dll` as an explicit assembly reference, `a.dll` has an assembly reference to `b.dll`, but `c.dll` is loaded though MEF or `Assembly.Load`, then `c.dll` may not be selected as part of ??? and therefore may not be copied to `bin\<configuration>\` despite being in `bin\<tfm>\`.
41+
42+
# Example
43+
44+
I wish my package to 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 will 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 & 10 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. Please see the page on [eExplicit assembles references](../create-packages/explicit-assembly-reference.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,15 +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-
316-
> [!Important]
317-
> The `<references>` element is only supported correctly by projects using NuGet packages with `packages.config`. In order to support projects using `PackageReference` (such as .NET Core projects), the reference assemblies should also be copied to the `ref/<TFM>/` directory in the package.
318-
>
319-
> For example, if your package contains `lib\netstandard2.0\A.dll` and `lib\netstandard2.0\B.dll`, and you have `<reference file="A.dll" />` in your nuspec, then you should copy `lib\netstandard2.0\A.dll` to `ref\netstandard2.0\A.dll` and have both in your package.
320-
321312
### Reference groups
322313

323314
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)