Utilizzo di System.Dynamic in Roslyn


96

Ho modificato l'esempio fornito con la nuova versione di Roslyn rilasciata ieri per utilizzare dynamic e ExpandoObject ma ricevo un errore del compilatore che non sono sicuro di come risolvere. L'errore è:

(7,21): errore CS0656: membro richiesto del compilatore mancante 'Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create'

Non puoi ancora usare le dinamiche nel nuovo compilatore? Come posso risolvere questo problema? Ecco l'esempio che ho aggiornato:

[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);
}

Risposte:


219

Penso che dovresti fare riferimento Microsoft.CSharp.dllall'assembly


3
Sì, questo è qualcosa che è stato richiesto da quando è dynamicstato introdotto.
khellang

19
E se Microsoft fornisse un messaggio di errore che ti diceva che questo, renderebbe le cose molto più semplici.
kjbartel

1
Non so se questo abbia risolto il problema o meno, ma ho aggiunto <add namespace = "Microsoft.CSharp" /> nel mio nodo Views / Web.config <namespaces>. L'errore del compilatore ora è sparito.
Don Rolling

3
L'aggiunta di FWIW a Microsoft.CSharp.dll significa var scriptOptions = ScriptOptions.Default.WithReferences ("Microsoft.CSharp") cioè rilascia la dll. Mi ha bloccato per alcuni minuti :)
Jon H

@ JonH quindi dovremmo aggiungere quella riga a AssemblyInfo.cs o da qualche parte invece di fare riferimento alla dll?
NH.

9

Per far funzionare il codice in .Net Core 2.1 ho dovuto aggiungere questi riferimenti nella compilazione:

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),            
    }
);

Puoi cavartela con System.Linq.Expressions, System.Private.CoreLib, System.Runtime e Microsoft.CSharp, tutti come stringhe
Simon Mourier

7

Specifico per ASP.NET MVC:

È possibile ottenere questo errore in un controller MVC 6 se si dimentica di inserire [FromBody]un POSTmetodo.

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

Il progetto predefinito di .NETCore include già il Microsoft.CSharpriferimento, ma ottieni più o meno lo stesso messaggio.

Con l' [FromBody]aggiunta ora puoi pubblicare JSON e quindi accedere dinamicamente alle proprietà :-)


Ho pensato che non si applicasse alla domanda originale pubblicata nel 2014 (anche se volevo riconoscere che era utile.) Non ero sicuro di cosa fosse l'etichetta SO in una situazione del genere.
giovedì

Punto giusto:) L'ho appena aggiunto qui perché sembrava così oscuro e questa era una buona corrispondenza per
quell'errore

4

Potresti anche voler controllare le proprietà di tutti i riferimenti del tuo progetto. Assicurati che ogni riferimento utilizzi .NET più recente di 2.0. Ho un progetto che faceva riferimento a un altro progetto nella stessa soluzione e ho dovuto ricostruire la dipendenza utilizzando un nuovo target .NET Framework.

Vedi questo post .

Inoltre, non dimenticare di aggiungere il Microsoft.CSharpriferimento al tuo progetto principale come ha detto @Alberto.


1

Se il tuo progetto è destinato a .Net Core o .Net Standard, invece di aggiungere un riferimento puoi installare il pacchetto NuGet Microsoft.CSharp per risolvere questo errore.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.