Exportar (0) Imprimir
Expandir Tudo
Expandir Minimizar

Pré-Compilação do ASP.NET 2.0

Publicado em: 10 de janeiro de 2007
Por Israel Aéce

Nesta página

Pré-Compilação do ASP.NET 2.0
Formas de Pré-Compilação
Conclusão

Pré-Compilação do ASP.NET 2.0

Uma das mudanças mais impactantes do ASP.NET 2.0 em relação as versões anteriores, ASP.NET 1.x, é a forma de compilarmos a aplicação. Já estavamos acostumados durante a compilação da versão 1.x do ASP.NET, através do Visual Studio .NET, a geração de um arquivo do tipo DLL dentro do diretório \bin na raiz da aplicação, que correspondia a todo o código fonte da aplicação em questão.

Nas versões 1.x do ASP.NET tínhamos o conceito de Code-Behind que veio para tornar o ASP.NET muito mais elegante que o ASP clássico. Essa funcionalidade consiste em termos dois arquivos para cada página do site, ou seja, uma página ASPX que contém somente códigos HTML e uma página *.cs (C#) ou *.vb (VB.NET) (dependendo da linguagem escolhida para a aplicação), que é o CodeBehind. As páginas de CodeBehind herdam diretamente da classe base System.Web.UI.Page e o arquivo ASPX, em sua diretiva de página, indica qual o arquivo de CodeBehind que correspondia ao seu código e, em tempo de execução, o ASP.NET faz essa herança automaticamente. A imagem abaixo ilustra isso para ficar mais claro:

Cc580627.fig01(pt-br,MSDN.10).png

Figura 1 - CodeBehind - ASP.NET 1.x.

Como vemos, o arquivo de CodeBehind está "amarrado" com o arquivo de apresentação (ASPX) através de herança e, o sincronismo é fundamental. Sendo assim, os quando criamos controles via Drag & Drop no VS.NET, obrigatoriamente ele insere o código correspondente à criação deste controle no arquivo de CodeBehind, justamente para termos suporte total à este quando formos programar.

Para resolver esse problema a Microsoft introduziu o que chamamos de Partial Classes ou classe parcial. Elas nos dão uma maior flexibilidade, ou seja, agora o arquivo de código (*.vb ou *.cs) expande (isso é um novo termo) a classe de apresentação (ASPX). Isso quer dizer que, em runtime o ASP.NET combina, ou melhor, mescla uma classe com a outra e a torna uma classe única. Se notar, já não teremos a declaração de controles e os Events Hookups no arquivo de código, pois o ASP.NET também gerará isso automaticamente sem a necessidade de ter previamente declarado.

Quando invocamos pela primeira vez uma página ASPX, onde a aplicação na qual ela faz parte acabou de ser colocada em produção, há a necessidade de compilarmos todo o código da aplicação. Essa tarefa, executada apenas uma única vez (desde que se não mude nada) e gera um retardo na primeira chamada da página que, já é conhecido por desenvolvedores ASP.NET. Para reduzir esse retardo, a Microsoft criou formas de pré-compilarmos a aplicação, quais serão discutidas no decorrer deste artigo.

Formas de Pré-Compilação

Agora na versão 2.0 do ASP.NET já temos duas formas de pré-compilar a aplicação: In-place Pre-compilation e Pre-compilation For Deployment. Vamos a partir daqui analisar cada uma destas opções de compilação.

In-place Pre-compilation

Esta é a forma padrão de compilação do ASP.NET 2.0, ou seja, todas as páginas serão compiladas (inclusive as pastas especiais, como a App_Code) no local em que elas se encontram. Essa forma de compilação é utilizada quando trabalhamos com código in-line (esse tipo de código é quando embutimos o código que roda no servidor misturado com o código de apresentação (ASPX, HTML)) ou mesmo com arquivos *.vb e *.cs separadamente.

Como já podemos perceber, esse comportamento nos dá uma enorme flexibilidade, ou seja, assim que mudarmos algo em algum arquivo ASPX ou mesmo em alguma classe/código de servidor, basta salvarmos e rodar novamente a aplicação que as alterações já estarão em funcionamento. O grande ponto negativo desta forma de compilação é que a primeira requisição sempre será mais demorada, justamente pelo fato de que o ASP.NET deverá primeiramente compilar todos os arquivos ASPX, ASCX, além das pastas especiais como a App_Code; este é o comportamento normal, que é idêntico ao que já acontece na versão 1.x do ASP.NET.

Mesmo que o desenvolvedor não utilizou a forma de código in-line, o ASP.NET compila o arquivo que contém a apresentação (ASPX) e o arquivo de código (*.vb ou *.cs) correspondente, que é especificado no atributo CodeFile da diretiva @Page, na primeira vez que a página é solicitada. Vejamos abaixo as vantagens de desvantagens deste modelo:

Vantagens

  • Fácil de usar;

  • Ótimo para o desenvolvedor;

  • Muda o código e já roda a aplicação.

Desvantagens

  • Exige o código na máquina/servidor;

  • A segurança fica comprometida;

  • O arquivo de código e o ASPX estão sempre sincronizados;

  • Qualquer um poderá visualizar o código da aplicação.

Com a versão do .NET Framework 2.0, temos um novo utilitário chamado aspnet_compiler.exe, localizado dentro do diretório WINDIR%\Microsoft.NET\Framework\v2.0.50215\ e que se encarrega de pré-compilar as aplicações ASP.NET. No caso da compilação in-place, o resultado é armazenado dentro do diretório dos arquivos temporários do ASP.NET, que geralmente está localizado no seguinte endereço: %WINDIR%\Microsoft.NET\Framework\v2.0.50215\Temporary ASP.NET Files\. Como neste caso a compilação é feita no mesmo local, definimos então o diretório virtual que será o alvo da compilação e para isso utilizamos o utilitário aspnet_compiler.exe, como é mostrado abaixo:

aspnet_compiler -v /Teste
			

O parâmetro -v indica que é um caminho/diretório virtual e /Teste o nome do diretório virtual que está definido no IIS. Claro que o utilitário aspnet_compiler.exe não fornece apenas essa forma de compilação. Veremos abaixo suas outras funcionalidades bem como seus outros parâmetros.

Para finalizar essa forma de compilação é importante salientar que seu principal benefício é, além de ter o código disponível para alterarmos, termos um retorno mais rápido na primeira vez que uma página é requisitada mas, com uma grande vantagem, ou seja, ao pré-compilar a aplicação e um erro ocorrer, o aspnet_compiler falhará e mostrará o problema. Já os "warnings" também são exibidos pelo compilador mas, neste caso, a compilação não é abortada.

Pre-compilation For Deployment

Além da compilação in-place que vimos acima, temos ainda a compilação para distribuição, que consiste em armazenar o resultado da compilação em um diretório separado, e este é enviado para o servidor de produção. Além disso, ganhamos em segurança, pois todo o código da aplicação é completamente compilado, gerando uma espécie de "executável". Logo, se sua aplicação sofre mudanças constantes, talvez não seria ideal utilizar este modelo de compilação.

Também conseguimos essa forma de pré-compilação através do utilitário aspnet_compiler.exe, o qual já foi apresentado anteriormente, e que permite compilarmos todas as páginas e códigos da aplicação. Mas isso não é como acontece nas versões anteriores, ou seja, o código não é embutido em apenas um Assembly (arquivo DLL), mas sim em vários.

Basicamente informamos à esse utilitário de linha de comando o diretório que contém a aplicação e o diretório de destino da mesma aplicação depois de compilada. Vejamos abaixo a sintaxe para utilizar este utilitário:

aspnet_compiler -p C:\WebSite1 -f -v / C:\WebSiteFinal
			

Analisando o código acima vemos que o utilitário compilará a aplicação que está no diretório "WebSite1" e armazenará o resultado no diretório "WebSiteFinal". O parâmetro -f indica que a pasta e seu conteúdo devem ser sobrescrito caso exista. Já o parâmetro -p informa ao utilitário que o caminho que está sendo informado é um caminho físico. Já o parâmetro -v é utilizado para referirmos um caminho virtual, ou seja, de algum diretório dentro do IIS. Neste caso, o compilador utilizará este parâmetro para resolver as referências a partir da raiz da aplicação.

Para o exemplo deste artigo, a aplicação contém duas páginas ASPX e uma classe contida dentro da pasta especial App_Code. Depois de realizada a compilação da aplicação, temos dentro do diretório \bin da pasta "WebSiteFinal" os seguintes arquivos:

Cc580627.fig02(pt-br,MSDN.10).png

Figura 2 - Pasta \bin depois da aplicação compilada.

Nesse processo é também criado um arquivo chamado Precompiled.config na raiz da aplicação. Se analisarmos os "internals" do ASP.NET 2.0 com o Reflector, então chegamos a classe BuildManager do namespace System.Web.Compilation e conseguimos chegar a conclusão que o runtime faz a verificação deste arquivo para certificar se a aplicação é ou não pré-compilada. Se existir o arquivo ele ainda faz algumas verificações dentro do método ReadPrecompMarkerFile. Vejamos abaixo o código na íntegra, extraído através do Reflector:

private bool IsPrecompiledAppInternal
{
     get
     {
          if (!this._isPrecompiledAppComputed)
          {
               this._isPrecompiledApp = 
                    BuildManager.ReadPrecompMarkerFile(
                    HttpRuntime.AppDomainAppPathInternal, 
                    out this._isUpdatablePrecompiledApp);
               this._isPrecompiledAppComputed = true;
          }
          return this._isPrecompiledApp;
     }
}
//....
private static bool ReadPrecompMarkerFile(string appRoot, out bool updatable)
{
     updatable = false;
     string text1 = Path.Combine(appRoot, "PrecompiledApp.config");
     if (!File.Exists(text1))
     {
           return false;
     }
     XmlDocument document1 = new XmlDocument();
     try
     {
           document1.Load(text1);
     }
     catch
     {
           return false;
     }
     XmlNode node1 = document1.DocumentElement;
     if ((node1 == null) || (node1.Name != "precompiledApp"))
     {
           return false;
     }
     HandlerBase.GetAndRemoveBooleanAttribute(node1, "updatable", ref updatable);
     return true;
}
			

Se agora abrirmos qualquer página ASPX desta aplicação, encontraremos a seguinte mensagem: "This is a marker file generated by the precompilation tool, and should not be deleted!". Como a mensagem diz, isso é uma espécie de "marca" que indica que o arquivo ASPX encontra-se compilado em algum local. Apesar da mensagem dizer para não apagarmos o arquivos ASPX, podemos excluí-los e a aplicação continua funcionando normalmente desde que a opção “Verify that file exists” não esteja marcada nas opções do seu diretório virtual.

Porém um problema existe quando excluímos os arquivos ASPX do diretório, ou seja, se você definir uma página padrão para ser chamada quando o usuário digitar apenas o caminho até o diretório virtual (Exemplo: "http://localhost/Teste") da sua aplicação, você receberá um erro, pois o ASPNET não encontrará a página.

Se analisarmos a imagem acima veremos que para cada arquivo ASPX é criado um arquivo com extensão *.compiled dentro do diretório \bin, e dentro deste arquivo contém código XML que contém referências do arquivo ASPX e da classe/código (*.vb ou *.cs). Abaixo é mostrado o conteúdo de um destes arquivos:


<preserve 
     resultType="3" 
     virtualPath="/Default.aspx" 
     hash="7421446ce" 
     filehash="d14ee6041e266d10"      
     flags="10000" 
     assembly="App_Web_ukipp-jc" 
     type="ASP.Default_aspx">
    <filedeps>
        <filedep name="/Default.aspx" />
        <filedep name="/Default.aspx.cs" />
    </filedeps>
</preserve>
			

Além destes arquivos que vimos acima, ainda tempos os arquivos DLLs: App_Code.dll e App_Web_XXXXX.dll. O primeiro é responsável por armazenar o código que está contido na pasta App_Code da aplicação. Já o outro arquivo contém os códigos das páginas *.vb e *.cs da aplicação.

Como já podemos ver, a quantidade de arquivos gerados é enorme, e ainda existe um problema: a dificuldade no deployment. Como os nomes dos arquivos mudam a cada compilação, uma simples alteração no arquivo ASPX ou no código (*.vb ou *.cs) obrigará a recompilarmos a aplicação toda e distribuir novamente (podendo utilizar XCOPY) todos os arquivos da aplicação.

Mas é claro que para isso temos uma solução, ou seja, ao executarmos o utilitário aspnet_compiler.exe podemos passar o parâmetro -fixednames, que o obrigará a criar os arquivos sempre com o mesmo nome. Isso facilita bastante, já que será preciso apenas enviar ao diretório da aplicação este novo arquivo gerado pela nova página ASPX ou a DLL, se por acaso a alteração for efetuada no código. O código abaixo ilustra essa forma de compilação:

aspnet_compiler -p C:\WebSite1 -f -fixednames -v / C:\WebSiteFinal1
			

Agora, se analisarmos o resultado desta compilação, veremos que foi criado um arquivo DLL para cada página da aplicação:

Cc580627.fig04(pt-br,MSDN.10).png

Figura 3 - Utilizando o parâmetro -fixednames.

E para certificar que a página sem a pré-compilação não é acessível, colocamos uma nova página ASPX no diretório da aplicação e em seguida fazemos a requisição para a mesma no browser. O erro, como é mostrado abaixo, será exibido ao cliente informando que a página deve e não foi pré-compilada:

Cc580627.fig03(pt-br,MSDN.10).png

Como falamos, o parâmetro -fixednames ajuda bastante nestes casos, ou seja, bastaríamos recompilar em um diretório temporário e copiar os arquivos gerados devido a criação de uma nova página e mandar para o diretório da aplicação que já está em produção.

A vantagem desse modelo de compilação é que todo o seu código, inclusive os arquivos ASPX (que contém código HTML e Javascript), ASCX, ASHX e Arquivos *.Master ficam compilados, e ninguém conseguirá ver o código que tem lá dentro. Mas poderá haver situações em que você deseja que seus arquivos fiquem intactos, ou seja, que sejam enviados com o seu código fonte. Para isso, podemos passar o parâmetro -u (que indica updateable) e assim, podemos fazer alguma alteração nos arquivos ASPX, já que temos todo o fonte ali disponível.

É importante dizer que os arquivos de back-end, tais como Imagens, arquivos de configuração, CSS, são mantidos e enviados para o destino dentro da mesma estrutura.

Conclusão

Como podemos ver no decorrer deste artigo, a forma de compilação para o ASP.NET 2.0 mudou consideravelmente. Apesar de bastante diferente em relação à versão 1.x do ASP.NET, com certeza esse modelo nos traz grandes facilidades e recursos.

Mostrar:
© 2014 Microsoft