Usando System.Dynamic em Roslyn

96

Modifiquei o exemplo que vem com a nova versão do Roslyn que foi lançada ontem para usar Dynamic e ExpandoObject, mas estou recebendo um erro do compilador que não tenho certeza de como corrigir. O erro é:

(7,21): erro CS0656: Compilador ausente requer membro 'Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create'

Você ainda não pode usar a dinâmica no novo compilador? Como posso consertar isso? Aqui está o exemplo que atualizei:

[TestMethod]
public void EndToEndCompileAndRun()
{
    var text = @"using System.Dynamic;
    public class Calculator
    {
        public static object Evaluate()
        {
            dynamic x = new ExpandoObject();
            x.Result = 42;
            return x.Result;
        } 
    }";

    var tree = SyntaxFactory.ParseSyntaxTree(text);
    var compilation = CSharpCompilation.Create(
        "calc.dll",
        options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary),
        syntaxTrees: new[] {tree},
        references: new[] {new MetadataFileReference(typeof (object).Assembly.Location), new MetadataFileReference(typeof (ExpandoObject).Assembly.Location)});

    Assembly compiledAssembly;
    using (var stream = new MemoryStream())
    {
        var compileResult = compilation.Emit(stream);
        compiledAssembly = Assembly.Load(stream.GetBuffer());
    }

    Type calculator = compiledAssembly.GetType("Calculator");
    MethodInfo evaluate = calculator.GetMethod("Evaluate");
    string answer = evaluate.Invoke(null, null).ToString();

    Assert.AreEqual("42", answer);
}
Rush Frisby
fonte

Respostas:

219

Eu acho que você deve fazer referência à Microsoft.CSharp.dllmontagem

Alberto
fonte
3
Sim, isso é algo necessário desde que dynamicfoi introduzido.
khellang
19
E se a Microsoft fornecesse uma mensagem de erro informando isso, tornaria as coisas muito mais fáceis.
kjbartel
1
Não sei se isso corrigiu o problema ou não, mas adicionei <add namespace = "Microsoft.CSharp" /> em meu nó Views / Web.config <namespaces>. O erro do compilador desapareceu agora.
Don Rolling
3
FWIW adicionar Microsoft.CSharp.dll significa var scriptOptions = ScriptOptions.Default.WithReferences ("Microsoft.CSharp"), ou seja, eliminar a dll. Me deixou perplexo por alguns minutos :)
Jon H
@JonH, então devemos adicionar essa linha ao AssemblyInfo.cs ou em algum lugar ao invés de fazer referência à dll?
NH.
9

Para fazer o código funcionar em .Net Core 2.1, tive que adicionar estas referências na compilação:

var compilation = CSharpCompilation.Create(
    "calc.dll",
    options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary),
    syntaxTrees: new[] {tree},
    references: new[] {
        MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
        MetadataReference.CreateFromFile(typeof(ExpandoObject).Assembly.Location),
        MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("Microsoft.CSharp")).Location),
        MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("netstandard")).Location),
        MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("mscorlib")).Location),
        MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("System.Runtime")).Location),            
    }
);
Renzo Ciot
fonte
Você pode se safar com System.Linq.Expressions, System.Private.CoreLib, System.Runtime e Microsoft.CSharp, todos como strings
Simon Mourier
7

Específico da ASP.NET MVC:

Você pode obter esse erro em um controlador MVC 6 se esquecer de inserir [FromBody]um POSTmétodo.

    [HttpPost("[action]")]
    public void RunReport([FromBody]dynamic report)
    {
        ...
    }

O projeto padrão .NETCore já inclui Microsoft.CSharpreferência, mas você recebe praticamente a mesma mensagem.

Com [FromBody]adicionado, agora você pode postar JSON e então acessar dinamicamente as propriedades :-)

Simon_Weaver
fonte
Achei que não se aplicava à pergunta original postada em 2014 (embora quisesse reconhecer que foi útil). Não tinha certeza do que a etiqueta do SO ditava em tal situação.
tj
Ponto justo :) Acabei de adicioná-lo aqui porque parecia muito obscuro e foi uma boa combinação para esse erro
Simon_Weaver
4

Você também pode verificar as propriedades de todas as referências do seu projeto. Certifique-se de que qualquer referência esteja usando .NET mais recente que 2.0. Tenho um projeto que fazia referência a outro projeto na mesma solução e precisava reconstruir a dependência usando um destino de estrutura .NET mais recente.

Veja esta postagem .

Além disso, não se esqueça de adicionar a Microsoft.CSharpreferência ao seu projeto principal, como @Alberto disse.

A.Clymer
fonte
1

Se o seu projeto tiver como objetivo .Net Core ou .Net Standard, em vez de adicionar referência, você pode instalar o pacote Microsoft.CSharp NuGet para solucionar esse erro.

Kolappan N
fonte