C# - Apresentando a Scripting API (Roslyn)
Você sabia que pode criar scripts na linguagem C# ? E que ela possui uma API de Scripts ? |
Embora seja muito pouco comentado o recurso para criar Scripts na linguagem C# não é uma novidade.
Desde o lançamento do compilador Roslyn (2015/2016) a linguagem C# possui uma API de Scripts que permite que os aplicativos avaliem o código em tempo de execução, fornecendo à API a implementação de uma excelente experiência de script.
Este recurso pode ser usado para avaliar código em tempo de execução e pode ser usado em uma variedade de cenários como por exemplo em um tomador de decisão onde você define um conjunto de regras e em cada regra pode avaliar os parâmetros de entrada e com base nisso, fornecer uma saída.
Para usar este recurso basta instalar no seu projeto o pacote:
Install-Package Microsoft.CodeAnalysis.CSharp.Scripting -Version 3.6.0
Obs: A versão estável atual é a 3.6.0
Após isso é só usar. Veja um exemplo básico a seguir:
using Microsoft.CodeAnalysis.CSharp.Scripting;
using System;
namespace CShp_Scripting1
{
class Program
{
static void Main(string[] args)
{
int valor = 0;
string expressao = "100 * 2 + 80 / 2";
CSharpScript.EvaluateAsync<int>($"{expressao}")
.ContinueWith(s => valor = s.Result).Wait();
Console.WriteLine($"{expressao} = {valor}");
object resultado = null;
CSharpScript.EvaluateAsync("System.DateTime.Today.Year")
.ContinueWith(s => resultado = s.Result).Wait();
Console.WriteLine($"Hoje = {resultado}");
Console.ReadLine();
}
}
}
|
|
Aqui temos um exemplo de avaliação de expressões.
Podemos usar a avaliação fazendo um tratamento de exceções:
static void Main(string[] args)
{
try
{
int valor = 0;
string expressao = "500 / 2 - 100 * 2 + 50";
CSharpScript.EvaluateAsync<int>($"{expressao}")
.ContinueWith(s => valor = s.Result).Wait();
Console.WriteLine($"{expressao} = {valor}");
}
catch (CompilationErrorException e)
{
Console.WriteLine(string.Join(Environment.NewLine, e.Diagnostics));
}
Console.ReadLine();
}
|
E também com usar com parâmetros e com tipos:
public class Escola
{
public int numeroDeAlunos;
public int alunosPorClasse;
}
class Program
{
static void Main(string[] args)
{
var globals = new Escola { numeroDeAlunos = 90, alunosPorClasse = 15 };
int valor = 0;
CSharpScript.
EvaluateAsync<int>("numeroDeAlunos/alunosPorClasse", globals: globals)
.ContinueWith(s => valor = s.Result).Wait();
Console.WriteLine($"{globals.numeroDeAlunos} / {globals.alunosPorClasse} = {valor}");
Console.ReadLine();
}
}
|
Aqui estamos enviando os parâmetros para uma expressão e usando-os na lógica do script.
Podemos também criar um script para executar diversas vezes:
public class Escola { public int numeroDeAlunos; public int alunosPorClasse; } class Program
{
static void Main(string[] args)
{
var script = CSharpScript.
Create<decimal>("numeroDeAlunos/alunosPorClasse", globalsType: typeof(Escola));
script.Compile();
object valor = null;
for (int i = 100; i < 300; i+=40)
{
script.RunAsync(new Escola { numeroDeAlunos = i, alunosPorClasse = 6 })
.ContinueWith(s => valor = s.Result.ReturnValue).Wait();
Console.WriteLine("Numero de classes {valor}");
};
Console.ReadLine();
}
}
|
O resultado da execução acima é o seguinte:
Aqui estamos criando um script com parâmetros de um tipo e forçando a sua compilação e a seguir estamos executando diversas vezes o script passando valores para os parâmetros.
Para mais exemplos consulte o repositório no GitHub: https://github.com/dotnet/roslyn
"Porque a lei foi
dada por Moisés; a graça e a verdade vieram por Jesus Cristo."
João 1:17
Referências:
C# - StreamReader, StringReader e TextReader
C# - Imprimindo um arquivo texto -
C# - Usando OpenFileDialog - Macoratti
C# - Formatando arquivos textos -