Introdução
Um "Assembly" é uma colecção de módulos executáveis (.exe, .dll) e não executáveis (imagens, html, etc.), correspondendo à unidade mínima de código para reutilização, versionamento, e "Deployment" em aplicações .Net.
A "framework" .Net suporta dois tipos de "Assemblies":
- "Private"
- "Shared" ou "Strong named"
"Private assemblies"
Um "Assembly" privado é mantido dentro da pasta de uma aplicação e utilizado exclusivamente por essa aplicação, ou por outra aplicação, desde que instalada no mesmo directório.
Este tipo de "Assembly" é normalmente mais simples de construir e administrar, permitindo o "XCOPY Deployment".
Os "Private Assemblies" resolvem o problema típico do "DLL Hell" uma vez que cada aplicação possui a sua própria cópia da DLL. A desvantagem é que se for um componente partilhado por múltiplas aplicações, irão existir várias cópias do mesmo ficheiro.
"Shared assemblies"
Um "Shared Assembly" é instalado numa localização especifica do sistema, normalmente no directório "\Windows\Assembly". Este directório é conhecido por GAC – "Global Assembly Cache".
A "framework" .Net instala uma "shell extension" especial que permite explorar o GAC através do "Windows Explorer".
A inclusão ou remoção de "assemblies" no GAC apenas é possível com privilégios de administração.
A inclusão de "Assemblies" é feita utilizando o utilitário "GACUTIL", enquanto a remoção é feita através da opção "UnInstall" da "Shell extension" do "windows explorer".
Diferenças entre "Private Assemblies" e "Shared Assemblies"
- Gestão de versões: Um "Shared Assembly" suporta informação sobre a versão, e é possível manter no GAC diferentes versões do mesmo "assembly" sem que se verifique qualquer conflito. Cada aplicação continua a funcionar com a versão com que foi compilada. Os "Assemblies" privados também podem possuir informação de versão, mas esta informação não é utilizada pela "framework". Serve apenas como referência para o desenvolvimento.
- Robustez: Um "Shared Assembly" registado no GAC torna a aplicação mais robusta por duas razões:
- Quando um "Assembly" é adicionado ao GAC é feito um teste de integridade para garantir que não foi alterado desde a sua compilação.
- Apenas um utilizador com privilégios de administração pode adicionar ou remover elementos ao GAC.
- Eficiência: Um "Shared Assembly" registado no GAC é mais eficiente pois o "Run Time" consegue encontra-lo mais rapidamente e não necessita de fazer uma verificação de disponibilidade. Em alguns casos, se várias aplicações utilizarem o mesmo "Assembly", o "Run Time" consegue utilizar apenas uma versão instaciada em memória.
- "Side-by-side execution": Duas ou mais versões de um "Shared Assembly" podem ser executadas no mesmo processo. Por exemplo uma aplicação pode utilizar a versão 1.0 de um "assembly" e um outro "assembly" que por sua vez utiliza a versão 1.1 do primeiro "assembly".
- Segurança: Um "Shared Assembly" pode ser assinado digitalmente, garantindo a origem do seu programador bem como que o seu código não foi alterado.
Nota: A codificação de um "Private assembly" ou de um "Shared assembly" é feita da mesma forma, uma vez que a única diferença entre os dois tipos é apenas a definição de um atributo.Contudo, uma vez que o principal objectivo de um "shared assembly" é ser partilhado por várias aplicações, é necessário ter atenção aos recursos utilizados. Por exemplo se um "shared assembly" utiliza ficheiros numa localização fixa, outras chamadas de outros clientes podem alterar esses ficheiros.
"Assemblies" e "Strong Names"
- No caso dos "private assemblies", que existem apenas junto da aplicação, a probabilidade de existência de diferentes "assemblies" com o mesmo nome é pequena e a responsabilidade da sua gestão e da exclusiva responsabilidade do programador.
- No caso dos "shared assemblies", normalmente partilhados no GAC é vital que a "Run Time" do .Net consiga distinguir dois "assemblies" com o mesmo nome mas de autores diferentes.
- A "framework" .Net garante que o nome de um "shared assembly" é único ao nível do sistema, assignando um "Strong Name".
- Um "Strong Name" resulta da combinação do seu nome, versão, cultura, de uma chave pública e de um valor que representa a arquitectura do processador.
- Representada de uma forma textual, um "strong name" tem um aspecto semelhante ao seguinte: Mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, ProcessorArchitecture=x86 A geração de um "shared assembly" com "strong name" é feita em dois passos:
- É executado o utilitário de linha de comando "SN" que irá criar um ficheiro ".snk" que contém um par de chaves aleatórias (uma publica e uma privada). Este utilitário, que existe no directório "\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin" deve executado com a opção –k, da seguinte forma:
Sn –k MyKey.snk
- Este ficheiro deve ser bem guardado e utilizado para assinar digitalmente todos os "assemblies" de um autor ou de uma companhia.
- É adicionado um atributo de "assembly" que indica ao compilador que deve utilizar a chave pública contida no ficheiro .snk na compilação, introduzindo a linha seguinte no ficheiro "AssemblyInfo.vb":
Instalação de "assemblies" no GAC
É possível instalar um "assembly" no GAC de duas formas:
- "Drag-andDrop": Este método é extremamente simples. Basta utilizar o windows explorer e navegar até à pasta "\Windows\Assembly" e arrastar o ficheiro ".dll".
- Utilitário "GacUtil": Este método é também simples, tendo a vantagem de poder ser incluido num "script" de instalação.
Gacutil /i testassembly.dll
Uma vez que um dos objectivos do GAC é permitir a coabitação de diferentes versões do mesmo "assembly", a instalação não remove qualquer versão antiga. O programador ou o administrador da máquina deve ser responsável por manter no GAC apenas as versões necessárias, removendo as mais antigas. É também possível utilizar o comando gacutil com o parâmetro /u para remover as versões antigas antes de instalar uma nova.
O facto de adicionar um "assembly" ao GAC não o torna visível no "Add Reference" do "visual studio".
Para que o "assembly" apareça no "Add References" tornando a sua reutilização mais simples, é necessário proceder a um dos dois passos seguintes:
- Copiar o ficheiro ".dll" para o directório "\Program Files\Microsft Visual Studio 8\Common7\IDE\PublicAssemblies.
- Registar uma chave de "Registry" chamada por exemplo "MyAssemblies" dentro da pasta "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\AssemblyFolders, e colocar como valor "deafult" o endereço para um caminho de disco que corresponda a um directório onde existem os nossos "assemblies".