5

I have the below code working for .NET 4.8 class library which uses Assembly.ReflectionOnlyLoad

Code:

// Retrieve the doman assembly used by the compilation
Assembly baseAssembly = typeof(MyType).Assembly;

// Retrieve the location of the assembly and the referenced assemblies used by the domain
AssemblyName[] baseAssemblyReferences = baseAssembly.GetReferencedAssemblies();
List<string> baseAssemblyLocations = baseAssemblyReferences.Select(a => Assembly.ReflectionOnlyLoad(a.FullName).Location).ToList();
baseAssemblyLocations.Add(baseAssembly.Location);

// Create Compilation Parameters
CompilerParameters compileParams = new CompilerParameters()
{
    CompilerOptions = Constants.Assembly.CompileToLibrary,
    GenerateInMemory = true
};
compileParams.ReferencedAssemblies.AddRange(baseAssemblyLocations.ToArray());

// Create Code Provider
CSharpCodeProvider provider = new CSharpCodeProvider(new Dictionary<string, string>() {
        { Constants.Assembly.CompilerVersion, Constants.Assembly.CompilerVersion4 }
    });

// Attempt compilation
CompilerResults compileResult = provider.CompileAssemblyFromSource(compileParams, sourceCode);
if (compileResult.Errors.Count > 0)
{
    throw new Exception(compileResult.Errors[0].ErrorText);
}

// Store the assembly
Assembly = compileResult.CompiledAssembly;

Now, I am trying to migrate this code so that .NET Core API can consume it. So Far I have tried,

Code

// Retrieve the location of the assembly and the referenced assemblies used by the domain
string[] runtimeAssemblies = Directory.GetFiles(RuntimeEnvironment.GetRuntimeDirectory(), "*.dll");
// Create the list of assembly paths consisting of runtime assemblies and the inspected assembly.
var paths = new List<string>(runtimeAssemblies);
paths.Add("ExampleAssembly.dll");

// Create PathAssemblyResolver that can resolve assemblies using the created list.
var resolver = new PathAssemblyResolver(paths);
var mlc = new MetadataLoadContext(resolver);
List<string> baseAssemblyLocations = new List<string>();

using (mlc)
{
    Assembly assembly = mlc.LoadFromAssemblyPath("ExampleAssembly.dll");
    AssemblyName name = assembly.GetName();
    baseAssemblyLocations.Add(assembly.Location);
}

// Create Compilation Parameters
CompilerParameters compileParams = new CompilerParameters()
{
    CompilerOptions = Constants.Assembly.CompileToLibrary,
    GenerateInMemory = true
};
compileParams.ReferencedAssemblies.AddRange(baseAssemblyLocations.ToArray());

// Create Code Provider
CSharpCodeProvider provider = new CSharpCodeProvider(new Dictionary<string, string>() {
        { Constants.Assembly.CompilerVersion, Constants.Assembly.CompilerVersion4 }
    });

// Attempt compilation
CompilerResults compileResult = provider.CompileAssemblyFromSource(compileParams, sourceCode);
if (compileResult.Errors.Count > 0)
{
    throw new Exception(compileResult.Errors[0].ErrorText);
}

// Store the assembly
Assembly = compileResult.CompiledAssembly;

But, I am not getting the correct assemblies. Has anyone worked with MetadataLoadContext?

More info at, https://learn.microsoft.com/en-us/dotnet/standard/assembly/inspect-contents-using-metadataloadcontext

Mike Hofer
  • 16,477
  • 11
  • 74
  • 110
tRuEsAtM
  • 3,517
  • 6
  • 43
  • 83
  • Please explain what you mean by "_I am not getting the correct assemblies_" - and show us the actual values you're passing in `paths` into `PathAssemblyResolver` - and the exact exception messages. I suspect you're just forgetting to set `coreAssemblyName` in `MetadataLoadContext`. – Dai Jun 25 '23 at 04:27

0 Answers0