[C#作为Xamarin Forms应用程序中的脚本语言?

问题描述 投票:3回答:1

我需要能够在Xamarin Forms C#应用程序内执行一些小脚本,看到Microsoft.CodeAnalysis库中实现的'Roslyn'技术,我感到很兴奋。但是我无法使脚本起作用。注意,我正在尝试在应用程序中运行脚本,与Visual Studio无关。我很犹豫要生成一个外部DLL,并以某种方式从我的应用程序中调用它,但是如果需要的话,我会这样做。

我能够解析函数(使用CSharpSyntaxTree.ParseText),但是当我尝试创建最小的脚本(“ 1 + 2”)时,它每次都会引发异常:

Exception TypeInitializationException: The type initializer for 'AppContext' threw an exception.
Source: Microsoft.CodeAnalysis.Scripting
   Stack trace:   at Microsoft.CodeAnalysis.Scripting.Hosting.RuntimeMetadataReferenceResolver.ResolveTrustedPlatformAssemblyCore (System.String name, Microsoft.CodeAnalysis.MetadataReferenceProperties properties) [0x00007] in /_/src/Scripting/Core/Hosting/Resolvers/RuntimeMetadataReferenceResolver.cs:169 
   at Microsoft.CodeAnalysis.Scripting.Hosting.RuntimeMetadataReferenceResolver.ResolveReference (System.String reference, System.String baseFilePath, Microsoft.CodeAnalysis.MetadataReferenceProperties properties) [0x000d0] in /_/src/Scripting/Core/Hosting/Resolvers/RuntimeMetadataReferenceResolver.cs:154 
   at Microsoft.CodeAnalysis.Scripting.Script.GetReferencesForCompilation (Microsoft.CodeAnalysis.CommonMessageProvider messageProvider, Microsoft.CodeAnalysis.DiagnosticBag diagnostics, Microsoft.CodeAnalysis.MetadataReference languageRuntimeReferenceOpt) [0x000ac] in /_/src/Scripting/Core/Script.cs:276 
   at Microsoft.CodeAnalysis.CSharp.Scripting.CSharpScriptCompiler.CreateSubmission (Microsoft.CodeAnalysis.Scripting.Script script) [0x00021] in /_/src/Scripting/CSharp/CSharpScriptCompiler.cs:38 
   at Microsoft.CodeAnalysis.Scripting.Script.GetCompilation () [0x00008] in /_/src/Scripting/Core/Script.cs:142 
   at Microsoft.CodeAnalysis.Scripting.Script`1[T].GetExecutor (System.Threading.CancellationToken cancellationToken) [0x00008] in /_/src/Scripting/Core/Script.cs:359 
   at Microsoft.CodeAnalysis.Scripting.Script`1[T].RunAsync (System.Object globals, System.Func`2[T,TResult] catchException, System.Threading.CancellationToken cancellationToken) [0x0001b] in /_/src/Scripting/Core/Script.cs:463 
   at MyCompany.MyApp.AppViewModel.TryScript () [0x002d3] in C:\Workspace\Mobile\Apps\MyApp\MyApp\AppViewModel.cs:1067 
Exception ArgumentNullException: Value cannot be null.
   Parameter name: type
   Source: mscorlib
   Stack trace:   at System.Reflection.IntrospectionExtensions.GetTypeInfo (System.Type type) [0x00009] in /Library/Frameworks/Xamarin.iOS.framework/Versions/12.14.0.114/src/Xamarin.iOS/external/corefx/src/Common/src/CoreLib/System/Reflection/IntrospectionExtensions.cs:14 
   at Microsoft.CodeAnalysis.CoreClrShim+AppContext..cctor () [0x0000f] in /_/src/Compilers/Shared/CoreClrShim.cs:28 

[很多人试图做同样的事情并且遇到问题:

  • This site建议添加对mscorlib的引用,但这没有帮助。
  • This site没有任何建议
  • This site没有建议
  • here
  • 没有人回复this one
  • [我最喜欢的是this page,有问题的人被告知Roslyn不能使用.NET Core,这是.NET Core的错。

这是我现在在应用程序中所得到的,试图执行非常简单的脚本“ 1 + 2”:

using (var loader = new InteractiveAssemblyLoader())
{
   loader.RegisterDependency(typeof(object).Assembly);
   loader.RegisterDependency(typeof(AppContext).Assembly);
   loader.RegisterDependency(typeof(Enumerable).Assembly);
   var script = CSharpScript.Create<int>("1 + 2", assemblyLoader: loader);
   var result = await script.RunAsync();
   Debug.WriteLine("   Script returned " + result);
}
xamarin scripting roslyn
1个回答
0
投票

[直到这里有Roslyn的一个更好的故事,您可以考虑在Xamarin.Forms iOS或Android应用程序中使用Mono Evaluator进行动态代码评估。

  1. 添加对Mono.CSharp.dll的引用
  2. 准备评估者
var cc = new CompilerContext(new CompilerSettings(), new ReportPrinter())
var evaluator = new Evaluator(cc);

// add assembly references
evaluator.ReferenceAssembly(..);
  1. 评估脚本
evaluator.Evaluate("1 + 1", out var result, out _);
Console.WriteLine(result); // 2

evaluator.Run("public class NewClass { public string HelloWorld => \"Hello World\"; }");
evaluator.Evaluate("new NewClass().HelloWorld", out result, out _);
Console.WriteLine(result); // "Hello World"

在iOS模拟器上,您需要--enable-repl mtouch标志。在iOS设备上,您需要--interpreter标志,并使用启用了Reflection.Emit的Xamarin.iOS / Mono版本进行构建。我不确定当前是否在启用RefEmit的情况下发布稳定的版本,但我之前曾在here中撰写过用此版本烘烤自己的版本的信息。如果您确定动态加载外部生成的程序集就足够了,那么您可以在今天的Xamarin.iOS构建中仅使用--interpreter标志就可以摆脱困境。

(请注意(以我的经验),评估程序支持的C#语言功能落后于Roslyn等效语言,请避免在C#6之后引入的功能最可靠。

© www.soinside.com 2019 - 2024. All rights reserved.