Utilisation de System.Dynamic dans Roslyn

96

J'ai modifié l'exemple fourni avec la nouvelle version de Roslyn qui a été publiée hier pour utiliser dynamic et ExpandoObject mais j'obtiens une erreur de compilation que je ne sais pas comment corriger. L'erreur est:

(7,21): erreur CS0656: membre requis du compilateur manquant «Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create»

Vous ne pouvez pas encore utiliser la dynamique dans le nouveau compilateur? Comment puis-je réparer cela? Voici l'exemple que j'ai mis à jour:

[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
la source

Réponses:

219

Je pense que vous devriez référencer l' Microsoft.CSharp.dllassemblage

Alberto
la source
3
Oui, c'est quelque chose qui est nécessaire depuis dynamicson introduction.
khellang
19
Et si Microsoft donnait un message d'erreur qui vous disait que cela rendrait les choses tellement plus faciles.
kjbartel le
1
Je ne sais pas si cela a résolu le problème ou non, mais j'ai ajouté <add namespace = "Microsoft.CSharp" /> dans mon nœud Views / Web.config <namespaces>. L'erreur du compilateur a disparu maintenant.
Don Rolling
3
L'ajout de FWIW Microsoft.CSharp.dll signifie var scriptOptions = ScriptOptions.Default.WithReferences ("Microsoft.CSharp") c'est-à-dire supprimer la DLL. M'a étonné pendant quelques minutes :)
Jon H
@JonH donc nous devrions ajouter cette ligne à AssemblyInfo.cs ou quelque part au lieu de référencer la dll?
NH.
9

Pour que le code fonctionne dans .Net Core 2.1, j'ai dû ajouter ces références dans la compilation:

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
la source
Vous pouvez vous en sortir avec System.Linq.Expressions, System.Private.CoreLib, System.Runtime et Microsoft.CSharp, le tout sous forme de chaînes
Simon Mourier
7

Spécifique à ASP.NET MVC:

Vous pouvez obtenir cette erreur dans un contrôleur MVC 6 si vous oubliez de mettre [FromBody]une POSTméthode.

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

Le projet par défaut .NETCore inclut déjà une Microsoft.CSharpréférence, mais vous obtenez à peu près le même message.

Avec l' [FromBody]ajout, vous pouvez maintenant publier JSON et accéder dynamiquement aux propriétés :-)

Simon_Weaver
la source
Je pensais que cela ne s'appliquait pas à la question originale postée à partir de 2014 (mais je voulais reconnaître que c'était utile.) Je ne savais pas quelle étiquette SO dictait dans une telle situation.
tj
Bon point :) Je viens de l'ajouter ici car cela semblait si obscur et c'était un bon match pour cette erreur
Simon_Weaver
4

Vous pouvez également vérifier les propriétés de toutes les références de votre projet. Assurez-vous que toute référence utilise .NET plus récent que 2.0. J'ai un projet qui faisait référence à un autre projet dans la même solution et j'ai dû reconstruire la dépendance à l'aide d'une nouvelle cible .NET Framework.

Voir ce post .

N'oubliez pas non plus d'ajouter la Microsoft.CSharpréférence à votre projet principal comme l'a dit @Alberto.

A. Clymer
la source
1

Si votre projet cible .Net Core ou .Net Standard, au lieu d'ajouter une référence, vous pouvez installer le package Microsoft.CSharp NuGet pour résoudre cette erreur.

Kolappan N
la source