Skip to content

Commit b98db0f

Browse files
committed
Better descriptions
1 parent cce15da commit b98db0f

2 files changed

Lines changed: 60 additions & 33 deletions

File tree

Directory.Build.props

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@
1212
<Authors>jaredpar</Authors>
1313
<Title>Basic.Reference.Assemblies: Reference assemblies for use in Roslyn</Title>
1414
<PackageDescription>
15-
This package provides reference assemblies for use in Roslyn Compilation objects. This greatly
16-
simplifies the work involved in doing in memory compilations with the Microsoft.CodeAnalysis
17-
API. Developers can now create correct Compilations with reference sets from all of the major
18-
target frameworks: netcoreapp31, net50 and netstandard.
15+
This package provides reference assemblies for use in Roslyn Compilation objects. This greatly
16+
simplifies the work involved in doing in memory compilations with the Microsoft.CodeAnalysis
17+
API. Developers can now create correct Compilations with reference sets from all of the major
18+
target frameworks: netcoreapp31, net50 and netstandard.
1919
</PackageDescription>
2020
</PropertyGroup>
2121

README.md

Lines changed: 56 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,31 +5,15 @@ Basic compilations. Provide it code, a few options and a set of references and
55
it will provide an API to inspect the syntax, semantic model, diagnostics and
66
even generate DLLs / EXEs.
77

8-
These technologies are very straight forward to use when running on .NET
9-
Framework because implementation assemblies can substitute for reference
10-
assemblies. That means if a user wants to add a reference to `System.Core.dll'
11-
to the compiler all they need to do is use the runtime assembly:
8+
Getting references for .NET Core or .NET Standard to use with a `Compilation`
9+
is challenging because these are only shipped as physical files. In order to use
10+
them in a library the developer must do the heavy lifting of packaging them up
11+
as resources in their library and unpacking them at runtime.
1212

13-
```c#
14-
Assembly systemCoreAssembly = typeof(System.Linq.Enumerable).Assembly;
15-
string systemCorePath = systemCoreAssembly.Location;
16-
MetadataReference systemCoreRef = AssemblyMetadata.CreateFromFile(string path).GetReference();
17-
```
18-
19-
This does not work on .NET Core though because there is a strong split between
20-
reference and implementation assemblies. The above code will give you access to
21-
the implementation assembly on .NET Core and is not a supported input for
22-
compilation. Instead you need to get the actual reference assembly.
23-
24-
Unfortunately .NET Core and .NET Standard only ship reference assemblies as
25-
physical files. These are not easily consumable at runtime in a .NET library
26-
or application. Hence any .NET app which wants to use the reference assemblies
27-
must do the heavy lifting of packaging them up as resources and unpacking them
28-
at runtime.
29-
30-
The `DotNet.Reference.Assemblies` libraries takes care of this heavy lifting
31-
and provides the reference assemblies for `netstandard2.0`, `netcoreapp3.1` and
32-
`net5.0`. These can be easily integrated into the existing Roslyn APIs.
13+
The [Basic.Reference.Assemblies](https://www.nuget.org/packages/Basic.Reference.Assemblies/)
14+
library takes care of this heavy lifting and provides the reference assemblies
15+
for `netstandard2.0`, `netcoreapp3.1` and `net5.0`. These can be easily
16+
integrated into the existing Roslyn APIs.
3317

3418
```c#
3519
var code = @"
@@ -48,14 +32,57 @@ var compilation = CSharpCompilation
4832
.Create(
4933
"HelloWorld.dll",
5034
new[] { CSharpSyntaxTree.ParseText(code) },
51-
references: Net50.All);
35+
references: ReferenceAssemblies.Net50);
5236

5337
using var fileStream = new FileStream(@"p:\temp\helloworld.exe", FileMode.Create, FileAccess.ReadWrite);
5438
var emitResults = compilation.Emit(fileStream);
5539
```
5640

57-
These make it much simpler to approach compilation inside your libraries
58-
or application.
41+
This package also adds extensions methods for easily retargeting `Compilation`
42+
instances to different Target Frameworks.
43+
44+
```c#
45+
CSharpCompilation compilation = ...;
46+
compilation = compilation.WithReferenceAssemblies(ReferenceAssemblyKind.NetCoreApp31);
47+
```
48+
49+
This repository actually provides a series of packages. The expectation is that
50+
most developers will use [Basic.Reference.Assemblies](https://www.nuget.org/packages/Basic.Reference.Assemblies/).
51+
This package has reference assemblies for all of the supported target frameworks
52+
and provides APIs to make it easy to switch between them in `Compilation`
53+
instances.
54+
55+
# FAQ
56+
57+
## What if I only need a single target framework?
58+
Developers who only need a single target framework and are extremely size
59+
conscious can grab the target framework specific package:
60+
61+
- [Basic.Reference.Assemblies.Net50](https://www.nuget.org/packages/Basic.Reference.Assemblies.Net50/)
62+
- [Basic.Reference.Assemblies.NetCoreApp31](https://www.nuget.org/packages/Basic.Reference.Assemblies.NetCoreApp31/)
63+
- [Basic.Reference.Assemblies.NetStandard20](https://www.nuget.org/packages/Basic.Reference.Assemblies.NetStandard20/)
64+
65+
## What is wrong with using typeof(Enumerable).Assembly?
66+
Developers working on .NET Framework will often end up with the following pattern
67+
for creating `Compilation` instances:
68+
69+
```c#
70+
Assembly systemCoreAssembly = typeof(System.Linq.Enumerable).Assembly;
71+
string systemCorePath = systemCoreAssembly.Location;
72+
MetadataReference systemCoreRef = AssemblyMetadata.CreateFromFile(string path).GetReference();
73+
```
74+
75+
This pattern will often work on .NET Framework but will fail with running on
76+
.NET Core. The reason for this is due to the differences in reference and
77+
implementation assemblies. Reference assemblies are designed for use at build
78+
time while implementation assemblies are used at runtime. A particular type for
79+
a given target framework doesn't necessarily live in the same reference and
80+
implementation assembly. Also the set of implementation assemblies can be larger
81+
than the reference assemblies for the same target framework.
5982

60-
**Note** .NET Framework also has a split between reference and implementation
61-
assemblies but it is not as strong as on .NET Core.
83+
The reason the above tends to work on .NET Framework is the split between
84+
reference and implementation assemblies is not as pronounced. In most cases
85+
there is a 1:1 relationship. On .NET Core though the split is much more
86+
pronounced and it often requires probing for implementation assemblies to get a
87+
set which will work for building. This is a fragile process though, developers
88+
are much better off using the reference assemblies as intended by the .NET team.

0 commit comments

Comments
 (0)