Certificação Microsoft 70-487: Objetivo 5.6 – Share assemblies between multiple applications and servers

Esse é o último post da série sobre a certificação Microsoft 70-487. Os links para todos os posts estão aqui.

Olá pessoal, tudo bem?
Vamos ao último objetivo da certificação, o Share assemblies between multiple applications and servers.

Esse objetivo cobre como preparar o ambiente para usar assemblies entre múltiplos servidores, assinar assemblies com um strong name, fazer o deploy de assemblies para o GAC (global assembly cache), implementar versionamento de assemblies e criar um assembly manifest. Vamos lá?

Preparando O Ambiente Para Usar Assemblies Entre Múltiplos Servidores

Quando você faz o deploy da sua aplicação, todo o código (inclusive o .NET Framework) é compilado para assemblies (DLLs) que são lidos e carregados na memória pelo IIS. Em casos onde um servidor hospeda várias aplicações, vários assemblies serão deployados redundantemente. Por exemplo, se existem 3 aplicações MVC, o assembly System.Web.Mvc será carregado 3 vezes na memória. Isso aumenta o tempo de inicialização e o uso da memória do seu servidor.

Para essa seção, você deve entender 2 conceitos que o ASP.NET utiliza na hospedagem de aplicações para resolver esse problema: Shadow Copying e Assembly Interning.

Shadow Copying é útil no momento de atualização dos assemblies. Normalmente, o CLR (Commom Language Runtime) trava os assemblies quando eles estão em execução. Isso significa que você não pode simplesmente copiar uma nova versão em cima da atual. O Shadow Copying atua nesses cenários copiando o assembly original para a pasta de arquivos temporários do ASP.NET, travando a cópia e liberando a atualização do assembly na localização original. Isso é habilitado por padrão nas pastas de assemblies (bin).

O Assembly Interning, disponível a partir do ASP.NET 4.5, analisa essa pasta temporária procurando por assemblies duplicados (usados 3 vezes ou mais), como no caso de 3 aplicações MVC no mesmo servidor. Esses assemblies são então movidos para uma localização especial, e todas as referências originais são substituídas com “links simbólicos”, que apontam para essa nova localização quando as aplicações fazem requisições aos assemblies que foram compartilhados. Dessa forma, todos esses assemblies são carregados apenas uma vez na memória, economizando tempo e recursos.

Você usa o Assembly Interning pela ferramenta aspnet_intern.exe, na linha de comando. Ela pode ser usada assim:

aspnet_intern -mode exec -sourcedir "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files" -interndir C:\CommonAssemblies

Há também um modo de análise, onde a ferramenta mostra quais assemblies podem ser compartilhados:

aspnet_intern -mode analyze -sourcedir "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files" -v

Assinando Assemblies Com Um Strong Name

O CLR suporta dois tipos de assemblies: os regulares e os com strong name (“nome forte”). Ambos têm a mesma estrutura, mas os fortemente nomeados têm chaves públicas e privadas que identificam o publicador e o conteúdo do assembly.

Isso garante singularidade, pois nenhum assembly pode ter o mesmo nome forte que o seu (o nome é baseado na chave privada). Os outros benefícios são que somente você pode publicar atualizações para o assembly e que o .NET consegue checar a integridade do assembly desde o momento que ele foi assinado.

Você pode assinar um assembly via linha de comando ou pelo Visual Studio. O primeiro passo é gerar as chaves privada e pública por meio de um arquivo .snk. O seguinte comando gera esse arquivo:

sn -k myKey.snk

Pelo Visual Studio, isso é feito na página de Properties do projeto, na aba Signing:

signing

Habilitando a opção Sign the assembly, o Visual Studio gera o arquivo com a chave e assina o assembly no momento da compilação.

Assemblies assinados só podem referenciar assemblies que também são assinados por motivos de segurança. Caso você referencie um assembly não assinado, ao invocar qualquer código desse assembly o erro Assembly generation failed — Referenced assembly ‘MyLib’ does not have a strong name é lançado.

Após assinar um assembly, você pode ver a chave pública pela ferramenta Sn.exe, instalada no Visual Studio. O seguinte comando pode ser usado:

sn -Tp C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Data.dll

O resultado é o seguinte, onde o Public key token representa a chave pública:

Microsoft (R) .NET Framework Strong Name Utility Version 4.0.30319.17929 Copyright (c)
Microsoft Corporation. All rights reserved.
Identity public key (hash algorithm: Unknown): 00000000000000000400000000000000
Signature public key (hash algorithm: sha256): 002400000c800000
140100000602000000240000525341310008000001000100613399aff18ef1
a2c2514a273a42d9042b72321f1757102df9ebada69923e2738406c21e5b801552ab8d200a65a2
35e001ac9adc25f2d811eb09496a4c6a59d4619589c69f5baf0c4179a47311d92555cd006acc8b
5959f2bd6e10e360c34537a1d266da8085856583c85d81da7f3ec01ed9564c58d93d713cd0172c
8e23a10f0239b80c96b07736f5d8b022542a4e74251a5f432824318b3539a5a087f8e53d2f135f
9ca47f3bb2e10aff0af0849504fb7cea3ff192dc8de0edad64c68efde34c56d302ad55fd6e80f3
02d5efcdeae953658d3452561b5f36c542efdbdd9f888538d374cef106acf7d93a4445c3c73cd9
11f0571aaf3d54da12b11ddec375b3
Public key token is b77a5c561934e089

Para empresas, é importante manter a chave privada segura, pois alguém pode roubá-la e distribuir assemblies alterados que parecem legítimos. Porém, sem a chave privada, os desenvolvedores não conseguem assinar o assembly para construir a aplicação.

Para evitar esse problema, o conceito de delay/partial signing foi criado. Com isso, os desenvolvedores conseguem assinar o assembly somente com a chave pública, deixando para assinar o assembly com a chave privada somente no momento da publicação. Na figura acima no Visual Studio, a opção Delay sign only faz isso.

Lembre-se para o exame dos benefícios de assinar um assembly e quando usar delayed signing.

Fazendo O Deploy De Assemblies Para O GAC (Global Assembly Cache)

GAC (Global Assembly Cache) é uma biblioteca especializada em guardar assemblies. Fazer o deploy de um assembly para o GAC significa que ele estará disponível para todas as aplicações hospedadas naquele servidor.

Usar o GAC é útil quando um assembly é compartilhado entre múltiplas aplicações. Outra razão é para melhoria de segurança, visto que normalmente somente administradores conseguem alterar o GAC. O GAC também é conveniente para fazer o deploy de múltiplas versões do mesmo assembly.

Para o servidor de produção, você pode fazer o deploy de um assembly para o GAC por meio de alguma ferramenta como o Windows Installer 2.0 ou com o Web Deploy configurado com um provider para fazer a instalação do arquivo no GAC.

No ambiente de desenvolvimento, você usa uma ferramenta chamada Gacutil.exe. Os seguintes comandos podem ser utilizados:

  • gacutil -l lista o conteúdo do GAC;
  • gacutil -i [assembly name] instala um assembly no GAC;
  • gacutil -u [assembly name] remove um assembly do GAC.

Ao referenciar um assembly no seu projeto, você pode adicionar uma referência ao arquivo no GAC ou uma cópia local. Quando o Visual Studio detecta que há um assembly do GAC referenciado, ele adiciona a referência ao GAC.

Implementando Versionamento De Assemblies

Cada assembly carrega no seu manifesto o número da sua versão no seguinte formato: {Major}.{Minor}.{Build}.{Revision}.

Ao fazer o build de um assembly, há 2 números de versão que você deve levar em conta: a versão do arquivo e a versão do assembly .NET. Quando um projeto é criado no Visual Studio, o arquivo AssemblyInfo.cs é automaticamente criado contendo as seguintes linhas:

[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

AssemblyFileVersionAttribute é o que deve ser incrementado a cada build no seu processo de build. AssemblyVersionAttribute deve ser incrementado manualmente a cada deploy para produção.

Como dito anteriormente, múltiplas versões de um mesmo assembly podem ser deployados para o GAC. Isso é chamado side-by-side hosting.

O processo de encontrar o assembly correto para ser carregado pelo CLR começa no número da versão mencionado no manifesto. Mas isso pode ser influenciado por alguns arquivos de configuração, como o da aplicação, do Publisher Policy ou da Machine Configuration.

Vamos supor que você tem um assembly carregado no GAC e várias aplicações dependem dele. Caso você publique uma nova versão e queira forçar as aplicações a usarem essa nova versão, você pode publicar um Publisher Policy para o GAC com a seguinte configuração:

Nesse exemplo, quando o CLR procura o assembly com a versão 1.0.0.0, é redirecionado para o 2.0.0.0.

Caso todos os assemblies estejam privados dentro da aplicação, você pode adicionar a seção de probing no arquivo web.config para o CLR procurar em outro diretório. Exemplo:

Outra opção é usar o elemento codeBase para especificar uma localização fora do diretório da aplicação, podendo ser outro computador da rede ou algum lugar na internet.

Dois detalhes: os assemblies precisam ser fortemente nomeados (assinados) se estiverem fora da pasta da aplicação e os assemblies localizados em outro computador são baixados para uma pasta especial no GAC.

Um exemplo de configuração do codeBase:

Para o exame, lembre-se que a opção de probing só pode ser usada para localizações dentro do caminho da aplicação, enquanto o codeBase permite outras localizações.

Criando Um Assembly Manifest

O Assembly Manifest é o lugar que contém os metadados do assembly e de todos os assemblies que ele depende.

A ferramenta ILDasm analisa o conteúdo de assemblies compilados. Ela mostra da seguinte forma:

ildasm

Note a presença do Assembly Manifest. Ele tem as seguintes funções:

  • Enumera os arquivos do assembly;
  • Governa como as referências ao tipo do assembly são mapeadas para os arquivos que contém a implementação;
  • Enumera os assemblies que o assembly depende;
  • Provê um nível de separação entre os consumidores do assembly e os detalhes da implementação;
  • Renderiza a descrição do assembly.

Ele ainda contém a identidade do assembly, como o nome, o número da versão, cultura e informações da assinatura. Você pode alterar esses valores no arquivo AssemblyInfo.cs, com os atributos AssemblyCultureAttribute, AssemblyTitleAttribute e AssemblyDescriptionAttribute.

Por último, o Assembly Manifest normalmente está no Portable Executable (PE), como uma DLL ou .exe junto com o Intermediate Language (IL) que descreve o assembly. Você pode criar um assembly em múltiplos arquivos com um Assembly Manifest ou com o Assembly Manifest incorporado dentro de cada PE.


E finalmente, terminamos todos os objetivos da certificação 😀

Logo faço um post com algumas informações da prova, como as atualizações que vieram em abril de 2014 e algumas dicas a mais.

Obrigado por acompanhar essa jornada e até mais!