Search code examples
c#.netportable-class-libraryroslyn

Unable to load Rosyln generated PCL assembly in .NET (Full) 4.5 Console App


I am attempting to create a PCL assembly using Roslyn (Microsoft.CodeAnalysis). I'm referencing PCL assemblies located at "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETPortable\v4.5\Profile\Profile259". Here is my code that compiles the actual assembly.

var assemblyName = string.Concat("ODataHQ.SDK.", accountKey, ".dll");
var source = GenerateAccountSource(accountKey, workspace);
var assemblyInfoSource = GetAssemblyInfo(assemblyName);
var assemblyTree = CSharpSyntaxTree.ParseText(assemblyInfoSource);
var tree = CSharpSyntaxTree.ParseText(source);

// Lets add PCL framework assemblies.
var frameworkFiles = new[] {"mscorlib.dll", "Microsoft.CSharp.dll", "System.dll", "System.Core.dll", "System.Runtime.dll"};
var references = frameworkFiles
    .Select(file => Path.Combine(Settings.PCLProfilePath, file))
    .Select(fullPath => MetadataReference.CreateFromFile(fullPath))
    .Cast<MetadataReference>()
    .ToList();

// Lets add third-party dependent assemblies.
references.AddRange(Directory.GetFiles(Settings.SDKDependencyPath, "*.dll")
    .Select(file => MetadataReference.CreateFromFile(file)));

var options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary);
var compilation = CSharpCompilation.Create(assemblyName, new [] { assemblyTree, tree }, references, options);

var ms = new MemoryStream();
var result = compilation.Emit(ms);

if (result.Success)
{
    // Reset stream position to read from beginning.
    ms.Position = 0;
    return ms;
}

// Destroy memory stream since it didn't compile successfully.
ms.Dispose();

var firstError = result.Diagnostics
    .Where(d => d.Severity == DiagnosticSeverity.Error)
    .Select(d => d.GetMessage())
    .FirstOrDefault();

throw new CompilationException(firstError);

Here is my GetAssemblyInfo method:

private string GetAssemblyInfo(string assemblyName)
    {
        return @"using System.Reflection;
            using System.Runtime.Versioning;
            [assembly: AssemblyTitle(""" + assemblyName + @""")]
            [assembly: AssemblyVersion(""1.0.*"")]
            [assembly: AssemblyFileVersion(""1.0.*"")]
            [assembly: TargetFramework("".NETPortable,Version=v4.5,Profile=Profile259"", FrameworkDisplayName="".NET Portable Subset"")]";
    }

I take the assembly that is generated and save it to disk. Then reference it in another console app project. However, when I run the console app and try to use a type from the dynamically generated PCL assembly, I get the following error.

An unhandled exception of type 'System.IO.FileNotFoundException' occurred in mscorlib.dll Additional information: Could not load file or assembly 'ODataHQ.SDK.dvester.dll, Version=1.0.5635.36199, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.

Can someone help me figure out what's going wrong?


Solution

  • Check the FusionLog property of the exception (you may need to enable that in the registry).

    This will tell you why it failed.