We have an issue where simple c# code executed via CSharpCodeProvider doesn't work the same on running local command line and docker.
Code example is below, and it will not return any Types of the assembly when run on Roslyn, but works fine locally. I have literally no idea how to debug this from here - any help welcome!
using System;
using Microsoft.CodeDom.Providers.DotNetCompilerPlatform;
using System.IO;
using System.Reflection;
using System.Text;
using System.CodeDom.Compiler;
namespace TestContainerIssue
{
class Program
{
static void Main(string[] args)
{
using (var codeProvider = new CSharpCodeProvider())
{
var compilerParameters = new CompilerParameters
{
GenerateExecutable = false,
GenerateInMemory = true
};
compilerParameters.CompilerOptions = String.Format("/lib:\"{0}\"", Path.GetDirectoryName(Uri.UnescapeDataString((new UriBuilder(Assembly.GetExecutingAssembly().CodeBase)).Path)));
Console.WriteLine(compilerParameters.CompilerOptions);
compilerParameters.ReferencedAssemblies.Add("System.dll");
compilerParameters.ReferencedAssemblies.Add("System.Core.dll");
CompilerResults compilerResults = codeProvider.CompileAssemblyFromSource(compilerParameters, ExecutionWrapperCode);
if (compilerResults.Errors.HasErrors)
{
StringBuilder errors = new StringBuilder();
foreach (CompilerError error in compilerResults.Errors)
errors.AppendLine(error.ErrorText);
throw new Exception(errors.ToString());
}
Console.WriteLine(compilerResults.PathToAssembly);
Assembly assembly = compilerResults.CompiledAssembly;
Console.WriteLine(assembly.FullName);
Console.WriteLine("Types:");
foreach (Type t in assembly.GetTypes())
{
Console.WriteLine(t);
}
Type type = assembly.GetType("Validation.Execution");
Console.WriteLine("Type:");
Console.WriteLine(type); //Empty when run in Docker (both mcr.microsoft.com/windows:1909 and mcr.microsoft.com/windows/servercore:ltsc2019
var methodInfo = type.GetMethod("Execute");
Console.WriteLine(methodInfo);
}
}
private const string ExecutionWrapperCode = @"
using System;
namespace Validation
{
public static class Execution
{
public static string Execute()
{
return ""test"";
}
}
}";
}
}
I tried below docker file (I tried two windows image: mcr.microsoft.com/windows:1909 and mcr.microsoft.com/windows/servercore:ltsc2019
FROM mcr.microsoft.com/windows/servercore:ltsc2019
ADD /bin/Debug /
ENTRYPOINT TestContainerIssue.exe
EDIT: I built the two dlls, and compared them in dotPeek - as you can see the one in Docker is missing the namespace. They are exactly the same bytes length though.
It turns out this line of code:
compilerParameters.CompilerOptions = String.Format("/lib:\"{0}\"", Path.GetDirectoryName(Uri.UnescapeDataString((new UriBuilder(Assembly.GetExecutingAssembly().CodeBase)).Path)));
was causing the problem. I don't know why it causes it and doesn't throw an error in compiler, but perhaps will help someone else. Was