dotnet / roslyn

The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs.
https://docs.microsoft.com/dotnet/csharp/roslyn-sdk/
MIT License
19.07k stars 4.04k forks source link

Best practice for loading assemblies in netstandard #34111

Open baruchiro opened 5 years ago

baruchiro commented 5 years ago

Version Used: Nuget Microsoft.CSharp Version=4.5.0

What are we trying to do?

My company has a very large base code, and one of the libraries compiles lots of C# code at runtime. We are trying to support .NET Core, and for this purpose, we are currently assembling the libraries to netstandard2.0, and the executable is coming out to certain customers in the .NET Framework and to other customers in the .NET Core.

We don't understand what is the right way to load the correct Assemblies according to TargetFramework:

For .NET Framework:

IReadOnlyCollection<MetadataReference> references = new[]
{
    MetadataReference.CreateFromFile(typeof(Binder).GetTypeInfo().Assembly.Location),
    MetadataReference.CreateFromFile(typeof(ValueTuple<>).GetTypeInfo().Assembly.Location),
    MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
    MetadataReference.CreateFromFile(typeof(Regex).Assembly.Location),
    MetadataReference.CreateFromFile(typeof(XmlAttribute).Assembly.Location),
    MetadataReference.CreateFromFile(typeof(Enumerable).Assembly.Location),
    MetadataReference.CreateFromFile(typeof(HashSet<>).Assembly.Location),
    MetadataReference.CreateFromFile(Assembly.Load("netstandard").Location)
};

return CSharpCompilation.Create(assemblyName, options: options, references: references);

But if we call this library from a .NET Core dll, we must add more assemblies likes these, to compile the same code:

MetadataReference.CreateFromFile(Assembly.Load("System.Runtime").Location)

But then, this code doesn't support .NET Framework anymore, because in .NET Framework, there is one assembly for all references, and the netstandard or System.Runtime are not exists.

So, we search for a common way to load assemblies for both .NET Core and .NET Framework.

From this Wiki page, we tried to use AppContext.GetData("TRUSTED_PLATFORM_ASSEMBLIES"), but again, for .NET Core it return a list of requierded dll's, but for .NET Framework it return null.

There is a common way to accomplish that, or we should load the assemblies by checking the Assembly.GetEntryAssembly().ImageRuntimeVersion?

baruchiro commented 5 years ago

It is more complicated from that.

About the Assembly.Load("netstandard") and .NET Framework, if I try to load it, it is not found. But if I don't load it, I get many exceptions about he is missing.

Meanwhile, I added this assembly file to my repository and I reference his location.

josefpihrt commented 3 years ago

About the Assembly.Load("netstandard") and .NET Framework, if I try to load it, it is not found. But if I don't load it, I get many exceptions about he is missing.

@baruchiro I was able to load netstandard assembly from .NET Framework when I specified its full name:

Assembly assembly = Assembly.Load("netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51");
MichaelWhi commented 2 years ago

With @JosefPihrt‘s reply, I think we can close the issue, can’t we? /close