Scripts em C#
Andre Claudinei Barsotti
Posted on September 14, 2021
Introdução
Scripts são uma ferramenta bem antiga nos ambientes de TI e ainda hoje são muito utilizados.
Sua natureza interpretada da à eles um dinamismo que supera em muito as facilidades de qualquer linguagem compilada.
JavaScript, com Node Js, e Python são exemplos que demonstram que a utilização de scripts no desenvolvimento de aplicações ainda segue em alta e sua força.
Estudando sobre Azure Functions me deparei com um arquivo a diferente extensão ".csx". Trata-se de um arquivo de scripts em linguagem C#, uma novidade para mim depois de vários anos trabalhando com essa linguagem.
Compartilho aqui com vocês o que aprendi sobre essa ferramenta e minhas conclusões.
Os scripts em C Sharp
Nos idos de 2011, Kirill Osenkov informou a comunidade .NET que a MS estava entregando o primeiro release preview do Roslyn Project. Nesse artigo, ele também informa que foi "introduzido o conceito de um arquivo de script C#" (OSENKOV, 2011). "A ideia principal por trás de escrever scripts em C# foi permitir que o código fosse avaliado dinamicamente pelo _runtime." (WOJ, 2015).
Para escrever um script C# você só precisa criar um arquivo com a extensão ".csx" em qualquer editor de textos. Depois de criar o arquivo você vai precisar de um programa para interpretá-lo. Hoje três opções:
- Mono/Roslyn CSI (que já vem instalado com o Visual Studio);
- cs-scripts;
- dotnet-scripts.
O cs-scripts e dotnet-scripts são multiplataforma, e dotnet-scripts tem a vantagem ser instalado com um dotnet tool
e rodar usando o .NET 5.
No restante desse artigo vamos utilizar o dotnet-scripts para nossos exemplos. Para instalá-lo digite o comando abaixo em seu console de preferência:
dotnet tool install -g dotnet-script
Sintaxe
"Um script C# tem requisitos de sintaxe mais flexíveis, então a experiência geral pode ser sem cerimônias. Abaixo estão algumas coisas a serem lembradas:
- o ponto de entrada para o seu script é a primeira linha do seu arquivo (nenhum método
Main
obrigatório)- qualquer código é permitido a partir da primeira linha (nenhuma classe de nível superior,
Program
, obrigatória)- funções globais são permitidas;
- sem
namespaces
;- sem um arquivo de projeto ou solução;
- seu script pode ser totalmente autocontido;
- instruções
using
e referências são importados implicitamente pelo aplicativo hospedeiro (responsável por executar o script)" (WOJCIESZYN, 2015)
Eu acrescento à essa lista o desenvolvimento de extensões, que foi algo que identifiquei nos meus testes.
Abaixo um exemplo de arquivo de script C# utilizado para inicializar o processo:
#load "Configs.csx"
#load "src/Data/TodoListRepository.csx"
#load "src/Services/TodoListService.csx"
#load "src/Controller/TodoListController.csx"
using Microsoft.Extensions.Configuration;
await Run(Args.ToArray());
async Task Run(string[] args)
{
using TodoListRepository repository = new(Configs.Configuration.GetConnectionString("db"));
TodoListService service = new(repository);
TodoListController controller = new(service);
await controller.ExecuteCommand(args);
}
Como pode ser visto a sintaxe da linguagem é a mesma já conhecida, só que sem a estrutura Program.Main
. A forma de referenciar outros arquivos ".csx" é utilizando a diretiva #load "<caminho do arquivo>"
.
Abaixo um exemplo de arquivo para leitura de configurações, que faz referência à pacotes nuget:
#r "nuget: Microsoft.Extensions.Configuration, 5.0.0"
#r "nuget: Microsoft.Extensions.Configuration.Binder, 5.0.0"
#r "nuget: Microsoft.Extensions.Configuration.UserSecrets, 5.0.0"
#r "nuget: Microsoft.Extensions.Configuration.EnvironmentVariables, 5.0.0"
using Microsoft.Extensions.Configuration;
public static class Configs
{
private static IConfiguration _config;
public static IConfiguration Configuration
{
get
{
if (_config is null)
SetConfig();
return _config;
}
}
private static void SetConfig()
{
_config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddUserSecrets("csx-script-app")
.AddEnvironmentVariables()
.Build();
}
public static T GetConfig<T>(string sectionName)
{
return Configuration.GetSection(sectionName).Get<T>();
}
}
Referenciar um pacote é bem simples utilizando #r "nuget: <nome do pacote>, <versão>"
.
Se for necessário importar um assembly próprio é utilize a direntiva #r "<caminho da dll>"
. Segue um exemplo:
#r: "./build/MeuAssembly.dll"
Desenvolvi um aplicativo Todo de exemplo e publiquei no meu GitHub onde é possível ver esses scripts em ação. Esse é o link do projeto.
Debug
Se você utiliza o Visual Studio Code como seu editor de texto/IDE debugar um script é algo que seguirá os padrões que você já esta acostumado. Basta configurar seu launch.json conforme abaixo, colocar o breakpoint e clicar em F5.
{
"version": "0.2.0",
"configurations": [
{
"name": ".NET Script Debug - Linux",
"type": "coreclr",
"request": "launch",
"program": "${env:HOME}/.dotnet/tools/dotnet-script",
"args": [
"${file}"
],
"cwd": "${workspaceFolder}",
"stopAtEntry": false,
},
{
"name": ".NET Script Debug - Windows",
"type": "coreclr",
"request": "launch",
"program": "dotnet",
"args": [
"${env:USERPROFILE}/.dotnet/tools/.store/dotnet-script/1.2.1/dotnet-script/1.2.1/tools/net5.0/any/dotnet-script.dll",
"${file}"
],
"cwd": "${workspaceRoot}",
"stopAtEntry": false
}
]
}
Compilação com um aplicativo e execução no Linux.
Um ponto interessante que achei utilizando o dotnet-script
no Windows foi a possibilidade de criar um aplicativo autocontido. Para fazer isso é muito simples basta publicar o script como no exemplo abaixo:
dotnet script publish Main.csx
Um diretório publish será criado com um executável. Como é um aplicativo autocontido, basta copiá-lo para qualquer computador e, mesmo sem o .NET instalado, executá-lo.
Em um ambiente Linux incluindo como primeira linha a diretiva #!/usr/bin/env dotnet-script
é possível executar o script como qualquer outro, lembrando que é preciso dar permissão de execução no arquivo.
Conclusão e aplicações
Observando a tecnologia vemos que essa ferramenta é bem madura e que vem se desenvolvendo junto com a plataforma e que irá continuar nesse caminho no futuro.
Hoje é possível escrever um programa console em C# de forma minimalista sem uma classe Program, um método Main e com funções globais, algo que até pouco tempo atrás era impensável. Com scripts C# você consegue tudo isso e ainda a vantagem de desenvolver sem um ".csproj" e sem o tempo de compilação, apenas escrever o código e já validar seu programa prontamente.
Testes de integração que serão executados sob demanda; programas de carga que serão utilizados apenas uma vez; pequenos testes e estudos de algum pacote Nuget novo; Scripts de configuração de ambiente. Esses são apenas alguns exemplos de utilização de scripts em C#.
No caso de scripts para configuração de ambiente ou inicialização de uma aplicativo, ainda existe a vantagem latente de seguir com a mesma linguagem que o projeto foi desenvolvido. Para a equipe isso é uma vantagem, visto que é preciso um esforço adicional para aprender e escrever o mesmo script com um bash script ou bat tradicional.
Em programas de carga existe ainda a vantagem de conseguir reaproveitar o código e as regras de negócio do próprio projeto, sem duplicidades.
As aplicações são muitas e certamente vale a pena incluir no "arsenal".
Referências
BAHRAMINEZHAD, Ali. Hitchhiker’s Guide to the C# scripting. ITNEXT, 2019. Disponível em: <https://itnext.io/hitchhikers-guide-to-the-c-scripting-13e45f753af9>. Acesso em: 11-09-2021
MICHAELIS, Mark. C# Scripting. Microsotf Docs, 2016. Disponível em: <https://docs.microsoft.com/en-us/archive/msdn-magazine/2016/january/essential-net-csharp-scripting>. Acesso em: 11-09-2021
OSENKOV, Kirill. Introducing the Microsoft “Roslyn” CTP. Microsoft DevBlogs, 2011. Disponível em <https://devblogs.microsoft.com/visualstudio/introducing-the-microsoft-roslyn-ctp/>. Acesso em: 12-09-2021
SALVADEO, André C B. Todo List em C# script (CSX). Github, 2021. Disponível em <https://github.com/andrebarsotti/csx-script-sample>. Acesso em: 12-09-2021
VOGEL, Peter. Making Your Life Easier with C# Scripting. Visual Studio Magazine, 2021. Disponível em: <https://visualstudiomagazine.com/articles/2021/06/14/csharp-scripting.aspx>. Acesso em: 11-09-2021
WOJCIESZYN, Filip. Dotnet script. Github, 2021. Disponível em <https://github.com/filipw/dotnet-script>. Acesso em: 11-09-2021
WOJCIESZYN, Filip. Adding C# scripting to your development arsenal - Part 1. Microsoft Docs - Blog Archive - Canadian Developer Connection, 2015. Disponível em <https://docs.microsoft.com/pt-br/archive/blogs/cdndevs/adding-c-scripting-to-your-development-arsenal-part-1>. Acesso em: 12-09-2021
Posted on September 14, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.