Arquitetura .Net
Aqui vamos entender: MSIL (Microsoft Intermediate
Language), CLR (Common Language Runtime), CTS (Common Type System),
CLS (Common Language Specification), BLC (Base Class Library),
Metadados ou METADATAS, Assembly, PE (Portable Executable), Compilação
JIT (Just in Time), VES (Virtual Execution System), GC (Garbage
Collector)
Antes de começarmos com um mundo de siglas
e nomes é muito importante entendermos que a plataforma
.NET↳.NET113 conteúdosNovidades do .NET 9 – o tipo genérico OrderedDictionaryDev (Back & Front) · dez 2024Novidades .NET 10: novas formas de uso do .NET CLIDev (Back & Front) · dez 2025Novidades do .NET 5: implementando um proxy reverso com YARP + ASP.NET 5Dev (Back & Front) · nov 2020Ver tudo em Dev (Back & Front) → tem sua complexidade. Mas quando entendida fica fácil
de partir para outros assuntos relacionados e é interessante
sabermos o que acontece em seu funcionamento e o motivo do porquê
a arquitetura .NET é desta forma. Vamos lá!
A plataforma .NET tem independência na linguagem
de programação: com ela é possível
trabalhar com várias linguagens diferentes no mesmo projeto
e interagir entre elas. Isso é possível por termos
uma IL (Intermediate Language), ou seja, linguagem intermediária
onde todos os fontes compilados pelo CLR (comentado mais a frente)
resultam em uma só linguagem.
Particularmente eu ainda não consegui entender
o motivo de alguns acharem que C# é melhor que VB.NET ou
vice-versa. Pois, se existe a IL e todo fonte é convertido
para essa linguagem, a IL, consequentemente dentro da plataforma
.NET todas as linguagens tem a mesma capacidade. E todas acessam
os mesmos objetos, então concluímos que todas também
tem o mesmo potencial.
Pelo que pude perceber até o momento não há
linguagem melhor ou pior. Há linguagem que você melhor
se adapta ou prefere.
Os sistemas desenvolvidos em .NET são auto-explicativos:
cada programa compilado contém em si informações
necessárias em METATAGS que faz com que o runtime não
precise procurar as informações no registro do Windows.
Por exemplo quando criamos um sistema, o mesmo pode ser executado
em qualquer máquina (que suporte a .NET) sem necessidade
da instalação. Todas as informações
necessárias para que o sistema seja executado são
encontrados dentro nas METATAGS dentro dele mesmo. Com isso temos
um sistema auto-explicativo, pois as informações
necessárias estão armazenadas dentro dele e não
no registro do sistema operacional.
MSIL (Microsoft Intermediate Language)
MSIL ou IL é a linguagem intermediária dita até
agora.
Independentemente da linguagem que você escrever seu programa
quando compilado será gerado a IL. Mas repare que não
é qualquer linguagem que pode ser compilada em .NET. Ela
deve aderir as especificações da CLS e CTS (comentadas
mais a frente) e só então e linguagem pode ser "nomeada"
como XYZ.NET, assim como Python.NET, Cobol.NET etc.
CLR (Common Language Runtime)
É o ambiente de execução das aplicações
.NET. O CLR cuidará do gerenciamento de memória
através do GC (visto mais a frente). Este gerenciamento
de memória torna o programa menos propício a erros.
Outro item muito interessantes da .NET é
a conversão da sua linguagem, por exemplo COBOL, para IL
e é neste estágio entra o compilador JIT (Just-in-Timer)
um componente da CLR que interpreta a IL e gera a linguagem de
máquina na arquitetura do processador.
CTS (Common Type System)
É a definição de tipos de dados onde tudo
é um objeto e deriva da classe System.Object, que é
o núcleo do sistema de tipos.
Pensando que tudo é um objeto, logo tudo
deriva da classe System.Object e, por isso, os projetistas da
.NET organizaram o sistema de tipos de dados de duas formas:
. Tipos
Valor: variáveis deste tipo são alocadas na pilha
e têm como classe base System.ValueType, que por sua vez
deriva da System.Object.
. Tipos
Referência: variáveis deste tipo são alocadas
na memória heap e têm a classe System.Object como
classe base.
Veja melhor como fica a estrutura de tipos com
esta separação:
— System.Object
—- Tipos valor
—— Estruturas
—— Tipos Enumerados
—- Tipo Referência
—— Objeto
—— Interface
—— Ponteiros
O que aconteceria se não fosse assim?
Seria da seguinte forma:
— System.Object
—- Estruturas
—- Tipos Enumerados
—- Objeto
—- Interface
—- Ponteiros
Não teria a diferença entre Tipo valor e Tipo referência.
CLS (Common Language Specification – Especificação
comum de dados)
Define um conjunto de regras que as linguagens que implementam
a .NET devem seguir para que a CLR possa gerar a IL.
Esse é um dos motivos de podermos criar
sistemas em diferentes linguagens e interagir entre elas dentro
da .NET. No momento da compilação é gerado
um código único intermediário (IL) e todas
essas linguagens suportadas pela .NET seguem as regras da CLS,
para que depois de gerado a IL, ela seja interpretada corretamente
pela CLR, como já dito acima.
BCL (Base Classe Library – Biblioteca de Classe
Base)
Como o próprio nome diz, na biblioteca de classe base você
encontra sistema de janelas, biblioteca de entrada/saída
de dados, sockets, gerenciamento de memória, etc.
Esta biblioteca é organizada em uma estrutura
conhecida como namespace, ou seja, imagine que você precise
atribuir um nome ao seu componente para que o mesmo possa ser
referenciado a partir de outro programa.Abaixo seguem alguns namespaces
da .NET
System:
Contém algumas classes de baixo nível usadas para
trabalhar com tipos primitivos, operações matemáticas,
gerenciamento de memória etc.
System.Collections:
Contém pilhas, filhas e listas encadeadas.
System.Data, System.Data.Common, System.Data.OleDb, System.Data.SqlClient:
Acesso a base de dados. Aqui também se encontra o ADO.NET
System.Diagnostics:
Log de Event, medição de performance, gerenciamento
de processos, depuração etc.
System.Drawing e namespace derivados:
A .NET oferece uma biblioteca de componentes para trabalhar com
gráficos, chamadas GDI+, que se encontra neste namespace.
System.IO:
Biblioteca para lidar com entrada e saída, gerenciamento
de arquivos etc.
System.NET:
Bibliotecas para programação de redes, sockets etc.
System.Reflection:
Biblioteca necessária para gerar código em tempo
de execução, descobrir tipo de variáveis
etc.
System.RuntimeInteropServices e System.Runtime.Remoting:
Fornece bibliotecas para interagir com código não-gerenciado.
System.Security:
Criptografia, permissão e todo o suporte referente à
segurança.
System.Threading:
Biblioteca para aplicações multithread
System.Web:
Biblioteca sobre tudo relacionado a Web, como Webservices, ASP.NET
etc.
System.Windows.Forms:
Bibliotecas para o desenvolvimento de aplicações
Windows tradicionais.
System.XML:
Biblioteca que permite a interação com documentos
XML.
Estrutura da arquitetura .NET em camadas:
Primeira: Linguagem de programação
preferida e aceita pela especificação da CLS e CTS.
Segunda: BCL (Base Class Library)
Terceira: CLR (Common Language Runtime)
Quarta: CTS (Common Type System) e CLS (Common Language Specification)
Explicando melhor as camadas e para que servem, ficaria da seguinte
forma:
Você usará sua linguagem de programação
preferida e que seja suportada pela .NET (primeira camada) e então
criar seus sistemas. E, para criá-los, você acessará
as classes da BCL, já que tudo é objeto em .NET.
(segunda camada)
Feito isso, seu programa deverá ser compilado e então
gerado a IL que, por sua vez, será interpretada pela CLR
(terceira camada), que deverá passar pelas especificações
da CTS e CLS (quarta camada).
Metadados ou METADATA
Seu programa feito na plataforma .NET, como já dito,
não utiliza o registro do Windows por ser auto-explicativo.
As informações são armazenadas em METADATA
dentro de cada programa no momento da compilação.
Que informações são essas?
. Descrição
dos tipos (classes, estruturas, tipos enumerados etc) usado na
aplicação, podendo esta ter sido gerada em forma
de DLL ou executável.
. Descrição
dos membros (propriedades, métodos, eventos etc.)
. Descrição
de cada unidade de código externo (assembly) usada na aplicação
e que é requerida para que esta execute adequadamente.
. Resolução
de chamada de método.
. Resolução
de versões diferentes de uma aplicação.
. Outra
coisa muito importante nas aplicações .NET é
que mesmo duas aplicações sendo homônimas,
elas convivem normalmente no mesmo ambiente. Isto acontece porque
na METADATA contem a versão de cada um, evitando o conflito
entre as aplicações. A CLR procura na METADATA a
versão correta da aplicação a ser executada.
Assembly
Toda aplicação .NET, quando compilada, é
armazenada fisicamente numa unidades de código denominada
assembly. Uma aplicação pode ser composta de um
ou mais assemblies, os quais são representados no sistema
de arquivos de sistema operacional host na forma de arquivos executáveis,
de extensão .EXE, ou de uma biblioteca de ligação
dinâmica melhor conhecida como DLL, de extensão .DLL.
PE (Portable Executable – Executável
Portável)
Isto significa que o fonte gerado poderá ser interpretado
(executado) em qualquer plataforma que tenha suporte .NET, sem
necessidade de recompilação do fonte.
Compilação JIT (Just in Time)
O compilador JIT, também conhecido como JITTER, converte
as instruções da IL para instruções
específicas da arquitetura do processador onde a aplicação
.NET esta sendo executada.
Temos três tipos de JITTER:
. Pre-JIT:
Compila de uma só vez todo o código da aplicação
.NET que esta sendo executada e o armazena no cache para uso posterior.
. Econo-JIT:
Utilizado em Hand-Helds onde a memória é um recurso
precioso. Sendo assim, o código é compilado sob
demanda e a memória alocada que não esta em uso
é liberada quando o dispositivo assim o requer.
. Normal-JIT:
Compila o código sob demanda e joga o código resultante
em cache, de forma que esse código não precise ser
recompilado quando houver uma nova invocação do
mesmo método.
VES (Virtual Execution System – Sistema de execução
virtual)
É um processo de compilação e é aqui
onde o JITTER é ativado quando uma aplicação
.NET é chamada. O windows identifica que esta é
uma aplicação .NET e uma runtime Win32 passa o controle
para a runtime do .NET. Neste momento a compilação
do PE é efetuada e só então o código
assembly próprio da arquitetura do processador é
gerado para que a aplicação possa ser executada.
Vemos ver todos os processos em camadas:
. Primeira:
Sua linguagem de programação
. Segunda:
IL
. Terceira:
CLR (Compilador JIT – Código nativo gerenciado – Execução
do código)
. Quarto:
Dispositivo de saída: PentiumX, Mobile etc.
Em outras palavras as camadas e para que servem
ficaria da seguinte forma: Você desenvolve seu aplicativo
(primeira camada) e compila gerando a IL (segunda camada). Após
isto a CLR interpreta (quando o aplicativo for executado) e compila
com o JIT, gerando o código nativo da arquitetura do processador
e o executa (terceira camada). De acordo com o dispositivo de
saída é gerado um código nativo da arquitetura
do processador diferente (quarta camada).
GC (Garbage Collector – Coletor de Lixo)
Gerenciar memória não deve ser uma preocupação
de quem desenvolve sistemas para tratar sobre regras de negócio
e com .NET você não precisa se preocupar com o gerenciamento
de memória porque o GC faz isso pra você. Quando
uma área de memória não esta mais em uso,
o GC trata de liberá-la. E quando necessário a utilização
de um novo espaço o GC também faz isso pra você.
Não é por isso que você deixará de
finalizar seus objetos, mas caso isso aconteça (esta é
a pior das hipóteses) o GC tratará este caso.
Apesar de que mesmo você não trabalhando
com C/C++, em .NET você também poderá gerenciar
memória o que torna o desempenho maior. Em contrapartida
é considerado um método inseguro, conhecido como
"unsafe code".
E chegamos ao fim deste artigo, ou melhor, acabamos
de descobrir que ainda temos muito o que aprender. Caso você
tenha alguma dúvida ou sugestão sobre este artigo,
por favor mail-me.
Até a próxima!
Google contrata desenvolvedores JavaScript para Fuchsia
Google contrata desenvolvedores para dar suporte a JavaScript com Node.js para o Fuchsia, um sistema híbrido desenvolvido para computadores e apps android.







Redação iMasters



