@@ -5,31 +5,15 @@ Basic compilations. Provide it code, a few options and a set of references and
55it will provide an API to inspect the syntax, semantic model, diagnostics and
66even 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#
3519var 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
5337using var fileStream = new FileStream (@" p:\temp\helloworld.exe" , FileMode .Create , FileAccess .ReadWrite );
5438var 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