jaredpar / basic-reference-assemblies

Produce NuPkg files that have .NET Reference assemblies as resources
MIT License
96 stars 15 forks source link

Reference not found (WindowsBase) #20

Closed Jean-PhilippeGoerke closed 2 years ago

Jean-PhilippeGoerke commented 2 years ago

Hi,

I am trying to add runtime compilation to a project but am struggling a bit with setting up the references to the framework assemblies.

My code currently looks like this:

using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using Basic.Reference.Assemblies;
using Microsoft.CodeAnalysis.CSharp;

namespace DynamicCompilationWithWpf
{
    class Program
    {
        static void Main(string[] args)
        {
            string sourceCode = @"
public class TestClass
{
    public System.Windows.Point DummyMethod(System.Windows.Point p1)
    {
        return new System.Windows.Point(p1.Y, p1.X);
    }
}
";

            var syntaxTree = CSharpSyntaxTree.ParseText(sourceCode);
            var references = new List<Microsoft.CodeAnalysis.MetadataReference>(Net50.All);
            //references.Add(Microsoft.CodeAnalysis.MetadataReference.CreateFromFile(@"C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\5.0.0\ref\net5.0\WindowsBase.dll"));
            var options = new CSharpCompilationOptions(Microsoft.CodeAnalysis.OutputKind.DynamicallyLinkedLibrary)
                .WithPlatform(Microsoft.CodeAnalysis.Platform.X64)
                .WithOptimizationLevel(Microsoft.CodeAnalysis.OptimizationLevel.Release);

            var compilation = CSharpCompilation
                 .Create(
                     null,
                     new[] { syntaxTree },
                     references: references,
                     options: options);

            var stream = new MemoryStream();
            var emitResults = compilation.Emit(stream);
            if (!emitResults.Success)
                throw new Exception();

            Assembly dynamicAssembly = Assembly.Load(stream.ToArray());
            dynamic instance = dynamicAssembly.CreateInstance("TestClass");
            System.Windows.Point result = instance.DummyMethod(new System.Windows.Point(3, -1));
        }
    }
}

Here the project file:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0-windows</TargetFramework>
    <UseWPF>true</UseWPF>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Basic.Reference.Assemblies.Net50" Version="1.2.4" />
    <PackageReference Include="Microsoft.CodeAnalysis.Common" Version="3.11.0" />
    <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.11.0" />
  </ItemGroup>
</Project>

The error is 'Type System.Windows.Point or namespace cannot be found ...'. I can verify that the containing assembly (WindowsBase) is in the list created by Net50.All. When manually adding a reference to the list, the error disappears and the compilation succeeds.

Am I missing something here?

jaredpar commented 2 years ago

I believe the problem is that the System.Windows.Point type is only defined for net5.0-windows not the more general net5.0 TFM.

https://apisof.net/catalog/77322091-fc17-3d51-6123-16b1bcfd7087

This particular project doesn't have the OS specific reference assemblies included, it uses only the more general TFM