O que é um Assembly ? 02.01.12 0:53
Você já deve ter ouvido ou lido algumas vezes a palavra assembly na documentação.NET. Então você já deve saber o que é um assembly ou assemblies no plural ? Se entendeu este artigo vai procurar tornar as coisas mais claras para você.
O que é um assembly ?
Uma unidade lógica de código
Existe fisicamente como um arquivo EXE ou DLL
Pode conter um ou mais arquivos
Os arquivos que o compõem podem incluir qualquer tipo de arquivo como imagens , textos , etc.
Quando você compila o seu código fonte , por padrão , o arquivo EXE/DLL gerado é um assembly
Se o seu código não for empacotado como um assembly ele não poderá ser usado em qualquer outra aplicação
Ao falar da versão de um componente você estamos falando sobre a versão do assembly para a qual o componente pertence
Cada arquivo assembly contém informação sobre si mesmo. Esta informação é chamada de assembly manifest
Entendeu agora o que são assemblies ? Vou tentar juntar tudo em uma definição, lá vai...:
"Um assembly é uma coleção de um ou mais arquivos físicos (classes , imagens, textos , binários , recursos, etc) e representa uma unidade de distribuição , controle de versão , etc. Toda aplicação .NET deve ser constituída de um ou mais assembly."
Nota: O conceito de assembly não é o mesmo conceito de DLL COM , embora possamos citar algumas semelhanças :
Assim como uma DLL um assembly é uma unidade de distribuição.
O conceito de assembly manifest é similar ao das types librarys das DLLs
Um assembly não é uma aplicação.
O que é um assembly manifest ?
Uma estrutura de dados que armazena informação sobre um assembly.
Esta informação é armazenada dentro do próprio arquivo assembly(DLL/EXE)
A informação descreve como os elementos do assembly se relacionam e inclui : lista de arquivos constituintes , informação sobre a versão , nome do assembly, etc.
Este conjunto de informações é conhecido como metadata ou metadados.
Nota: O programa Microsoft Intermediate Language Disassembler (isdasm.exe) permite visualizar toda a estrutura de um assembly incluindo os seus metadados.
Para matar sua curiosidade ao lado temos a exibição do conteúdo de uma assembly usando o Isdasm.exe.
O que é um assembly privado (private) e um assembly compartilhado (shared) ?
Um assembly que é usado somente por uma única aplicação é chamado de private assembly (assembly privado).
Vamos supor que você criou uma DLL que encapsula a sua lógica de negócios. Esta DLL será usada somente pela sua aplicação cliente. Afim de executar a aplicação a sua DLL deve estar no mesmo diretório na qual a aplicação cliente esta instalada. Desta forma este assembly é privativo da sua aplicação e é chamado de um private assembly
Se você criar uma DLL de propósitos gerais que fornecerá funcionalidades que serão usadas por várias aplicações , ao invés de você copiar a DLL para cada cliente que vai usar a sua DLL você pode por a DLL em um local de acesso global como o global assembly cache. Neste caso seu assembly é chamado de shared assembly.
O que é o Global Assembly Cache (GAC) ?
O Global Assembly Cachenada mais é do que um pasta de disco especial onde todos os assemblys compartilhados deverão ser colocados. No Windows XP ele esta localizado na pasta : <drive>:\Windows\assembly conforme figura abaixo.
Desta forma os componentes .NET não precisam ser registrados como os componentes COM , e , se você tiver um assembly que será usado por múltiplas aplicações ele é armazenado no GAC. (Isto somente é possível se eles tiverem um nome compartilhado)
Se o assembly não for localizado no diretório local nem no GAC você ainda pode ter um endereço de localização no arquivo de configuração. A CLR pode então fazer o download do assembly e armazenar o assembly no cache de download.
Para colocar e remover assemblies do GAC você tem que ter privilégios de administrador do sistema por questão de segurança.
Você pode ter diferentes versões do mesmo assembly carregadas no GAC ao mesmo tempo , e, mesmo se um componente estiver rodando no GAC você pode incluir outra versão do mesmo componente.
Nota : Você pode ver a hierarquia de assemblies contidos no GAC usando o comando : tree gacno prompt do DOS. O resultado é exibido na figura abaixo. Como você pode ver o GAC é uma estrutura complexa de diretório que permite múltiplas versões de qualquer grupo e usa nomes fortes especiais para garantir que não seja possível um conflito de nome. Um assembly é armazenado em um diretório especial que usa o número de versão e um ID gerado individualmente.(veremos como fazer isto)
Como os assemblies evitam o inferno das DLLs (DLL Hell) ?
Se você não sabe o que é o inferno das DLLs (sorte sua) vou explicar.
Quando você instalava a sua aplicação no cliente geralmente tinha que instalar um número de DLLs . Acontece que um cliente podia instalar outras aplicações e estas podiam instalar as mesmas DLLs com versão diferente da sua DLL ; você acabava com múltiplas cópias da mesma DLL mas com versões diferentes, e , sua aplicação ou deixava de funcionar ou começa a dar vários problemas devido a incompatibilidade das DLLs. Sem contar que sua DLL podia ser sobreposta por outra DLL com versão diferente. Era um verdadeiro inferno.
O modelo COM surgiu com uma proposta para acabar com este problema . Nele as aplicações não teriam mais que procurar por DLLs nos seus próprios diretórios mas iriam procurá-las no diretório Windows. As solicitações por componentes seriam então enviadas para o registry do Windows. Assim , mesmo havendo diversas versões da mesma DLL na máquina , haveria apenas uma versão no registry e todos os clientes usariam a mesma versão.
Para que o modelo COM funcionasse cada nova versão de uma DLL deveria garantir compatibilidade com as versões anteriores. Infelizmente os desenvolvedores quebraram esta compatibilidade distribuindo componentes com propriedades e métodos modificados , removidos ou alterados.
O conceito de assembly resolve definitivamente este problema. Senão vejamos :
Como eu já mencionei existem os assemblies privados. Desta forma cada aplicação cliente referencia seu assembly em seu próprio diretório de instalação , dai , mesmo que existam múltiplas versões do mesmo assembly eles não estarão em conflito entre si. Para você entender melhor acompanhe o exemplo :
Você cria um assembly chamado Assembly1
Cria também uma aplicação cliente chamada Cliente1 que usa o Assembly1
Você instala o cliente em c:\Aplicacao1 e coloca o Assembly1 neste diretório
Após alguns dias você altera o Assembly1
Você então cria outra aplicação cliente chamada Cliente2 que usa este assembly alterado
Você instala a aplicação Cliente2 na pasta c:\Aplicacao2 e coloca o assembly alterado nesta pasta
Como cada aplicação cliente esta se referindo a sua própria versão do Assembly1 não há conflitos.
Vamos considerar agora o caso das assemblies compartilhadas. Neste caso é importante conhecer como as assemblies são versionadas. Todas as assemblies possui um número de versão na forma : major.minor.build.version
Se você alterar o assembly original a versão alterada será considerada compatível com a existente se as versões major e minor de ambos assemblies forem iguais.
Quando a aplicação cliente requisita um assembly o número da versão requisitada é verificada contra as versões disponíveis verificando as versões major e minor. Assim os componentes podem ter declaradas suas dependências de outros componentes e múltiplas versões do mesmo componente podem rodar na memória simultaneamente. (instanciação lado a lado) sem conflitos.
Como criar shared assemblies ?
Crie o código fonte do seu arquivo DLL/EXE
Gere o nome de assembly único usando o utilitário SN (Microsoft .NET Strong Name Utility)
Assine seu arquivo DLL/EXE com a chave privada modificando o arquivo AssemblyInfo
Compile seu arquivo DLL/EXE
Coloco arquivo compilado no Global Assembly Cache usando o utilitário gacUtil (Microsoft .NET Assembly Cache Utility)
Como criar um nome único para o assembly ?
A Microsoft usa um par de chaves pública e privada para identificar de forma única um assembly. Estas chaves são geradas usando o utilitário SN.exe ( procure na pasta X:\Arquivos de programas\Microsoft Visual Studio .NET\FrameworkSDK\Bin ) . A sintaxe comum é :
sn -k MeuArquivoDeChaves.snk
Onde : K indica que queremos gerar uma chave e MeuArquivoDeChaves.key é o nome do arquivo onde a chave vai estar armazenada.
Como assinar o arquivo DLL/EXE ?
Antes de colocar o assembly no GAC você precisa assiná-lo usando as chaves geradas. Você referencia a informação da assinatura em arquivo especial chamado AssemblyInfo.vb Você deve acrescentar uma linha que se pareça com a seguinte : <Assembly : AssemblyKeyFile(" c:\KeyFiles\MeuArquivoDeChaves.snk ") >
Na próxima vez que você compilar o projeto , as informações de chave serão incluídas no grupo.
Como instalar o assembly no GAC ?
Existem diversas formas de você instalar o assembly no GAC. Você pode usar o utilitário GACUtil.exe ( procure na pasta X:\Arquivos de programas\Microsoft Visual Studio .NET\FrameworkSDK\Bin ou pode arrastar e soltar o assembly usando o plug-in WIndows Explorer. A estrutura especial de diretório é criada automaticamente para você e seu assembly deverá aparecer na lista do GAC.
A vantagem de colocar assemblies no GAC é que o desempenho fica otimizado pois o runtime os localiza de forma mais rápida sem ter que verificar a segurança a cada carga do assembly.
E vou ficando por aqui. Espero que esta pequena introdução o ajude a compreender melhor os assemblies.
Aguarde mais artigos sobre o assunto ..
O que é um assembly ?
Uma unidade lógica de código
Existe fisicamente como um arquivo EXE ou DLL
Pode conter um ou mais arquivos
Os arquivos que o compõem podem incluir qualquer tipo de arquivo como imagens , textos , etc.
Quando você compila o seu código fonte , por padrão , o arquivo EXE/DLL gerado é um assembly
Se o seu código não for empacotado como um assembly ele não poderá ser usado em qualquer outra aplicação
Ao falar da versão de um componente você estamos falando sobre a versão do assembly para a qual o componente pertence
Cada arquivo assembly contém informação sobre si mesmo. Esta informação é chamada de assembly manifest
Entendeu agora o que são assemblies ? Vou tentar juntar tudo em uma definição, lá vai...:
"Um assembly é uma coleção de um ou mais arquivos físicos (classes , imagens, textos , binários , recursos, etc) e representa uma unidade de distribuição , controle de versão , etc. Toda aplicação .NET deve ser constituída de um ou mais assembly."
Nota: O conceito de assembly não é o mesmo conceito de DLL COM , embora possamos citar algumas semelhanças :
Assim como uma DLL um assembly é uma unidade de distribuição.
O conceito de assembly manifest é similar ao das types librarys das DLLs
Um assembly não é uma aplicação.
O que é um assembly manifest ?
Uma estrutura de dados que armazena informação sobre um assembly.
Esta informação é armazenada dentro do próprio arquivo assembly(DLL/EXE)
A informação descreve como os elementos do assembly se relacionam e inclui : lista de arquivos constituintes , informação sobre a versão , nome do assembly, etc.
Este conjunto de informações é conhecido como metadata ou metadados.
Nota: O programa Microsoft Intermediate Language Disassembler (isdasm.exe) permite visualizar toda a estrutura de um assembly incluindo os seus metadados.
Para matar sua curiosidade ao lado temos a exibição do conteúdo de uma assembly usando o Isdasm.exe.
O que é um assembly privado (private) e um assembly compartilhado (shared) ?
Um assembly que é usado somente por uma única aplicação é chamado de private assembly (assembly privado).
Vamos supor que você criou uma DLL que encapsula a sua lógica de negócios. Esta DLL será usada somente pela sua aplicação cliente. Afim de executar a aplicação a sua DLL deve estar no mesmo diretório na qual a aplicação cliente esta instalada. Desta forma este assembly é privativo da sua aplicação e é chamado de um private assembly
Se você criar uma DLL de propósitos gerais que fornecerá funcionalidades que serão usadas por várias aplicações , ao invés de você copiar a DLL para cada cliente que vai usar a sua DLL você pode por a DLL em um local de acesso global como o global assembly cache. Neste caso seu assembly é chamado de shared assembly.
O que é o Global Assembly Cache (GAC) ?
O Global Assembly Cachenada mais é do que um pasta de disco especial onde todos os assemblys compartilhados deverão ser colocados. No Windows XP ele esta localizado na pasta : <drive>:\Windows\assembly conforme figura abaixo.
Novamente podemos fazer uma comparação com o modelo COM de registro de componentes.
Se o componente não é encontrado no mesmo diretório da aplicação, a aplicação procura-o no GAC, do mesmo modo com o COM pesquisa o registro. Nota:os componentes .NET não precisam ser registrados no registro do WIndows como no modelo COM.
Se o componente não é encontrado no mesmo diretório da aplicação, a aplicação procura-o no GAC, do mesmo modo com o COM pesquisa o registro. Nota:os componentes .NET não precisam ser registrados no registro do WIndows como no modelo COM.
Desta forma os componentes .NET não precisam ser registrados como os componentes COM , e , se você tiver um assembly que será usado por múltiplas aplicações ele é armazenado no GAC. (Isto somente é possível se eles tiverem um nome compartilhado)
Se o assembly não for localizado no diretório local nem no GAC você ainda pode ter um endereço de localização no arquivo de configuração. A CLR pode então fazer o download do assembly e armazenar o assembly no cache de download.
Para colocar e remover assemblies do GAC você tem que ter privilégios de administrador do sistema por questão de segurança.
Você pode ter diferentes versões do mesmo assembly carregadas no GAC ao mesmo tempo , e, mesmo se um componente estiver rodando no GAC você pode incluir outra versão do mesmo componente.
Nota : Você pode ver a hierarquia de assemblies contidos no GAC usando o comando : tree gacno prompt do DOS. O resultado é exibido na figura abaixo. Como você pode ver o GAC é uma estrutura complexa de diretório que permite múltiplas versões de qualquer grupo e usa nomes fortes especiais para garantir que não seja possível um conflito de nome. Um assembly é armazenado em um diretório especial que usa o número de versão e um ID gerado individualmente.(veremos como fazer isto)
Como os assemblies evitam o inferno das DLLs (DLL Hell) ?
Se você não sabe o que é o inferno das DLLs (sorte sua) vou explicar.
Quando você instalava a sua aplicação no cliente geralmente tinha que instalar um número de DLLs . Acontece que um cliente podia instalar outras aplicações e estas podiam instalar as mesmas DLLs com versão diferente da sua DLL ; você acabava com múltiplas cópias da mesma DLL mas com versões diferentes, e , sua aplicação ou deixava de funcionar ou começa a dar vários problemas devido a incompatibilidade das DLLs. Sem contar que sua DLL podia ser sobreposta por outra DLL com versão diferente. Era um verdadeiro inferno.
O modelo COM surgiu com uma proposta para acabar com este problema . Nele as aplicações não teriam mais que procurar por DLLs nos seus próprios diretórios mas iriam procurá-las no diretório Windows. As solicitações por componentes seriam então enviadas para o registry do Windows. Assim , mesmo havendo diversas versões da mesma DLL na máquina , haveria apenas uma versão no registry e todos os clientes usariam a mesma versão.
Para que o modelo COM funcionasse cada nova versão de uma DLL deveria garantir compatibilidade com as versões anteriores. Infelizmente os desenvolvedores quebraram esta compatibilidade distribuindo componentes com propriedades e métodos modificados , removidos ou alterados.
O conceito de assembly resolve definitivamente este problema. Senão vejamos :
Como eu já mencionei existem os assemblies privados. Desta forma cada aplicação cliente referencia seu assembly em seu próprio diretório de instalação , dai , mesmo que existam múltiplas versões do mesmo assembly eles não estarão em conflito entre si. Para você entender melhor acompanhe o exemplo :
Você cria um assembly chamado Assembly1
Cria também uma aplicação cliente chamada Cliente1 que usa o Assembly1
Você instala o cliente em c:\Aplicacao1 e coloca o Assembly1 neste diretório
Após alguns dias você altera o Assembly1
Você então cria outra aplicação cliente chamada Cliente2 que usa este assembly alterado
Você instala a aplicação Cliente2 na pasta c:\Aplicacao2 e coloca o assembly alterado nesta pasta
Como cada aplicação cliente esta se referindo a sua própria versão do Assembly1 não há conflitos.
Vamos considerar agora o caso das assemblies compartilhadas. Neste caso é importante conhecer como as assemblies são versionadas. Todas as assemblies possui um número de versão na forma : major.minor.build.version
Se você alterar o assembly original a versão alterada será considerada compatível com a existente se as versões major e minor de ambos assemblies forem iguais.
Quando a aplicação cliente requisita um assembly o número da versão requisitada é verificada contra as versões disponíveis verificando as versões major e minor. Assim os componentes podem ter declaradas suas dependências de outros componentes e múltiplas versões do mesmo componente podem rodar na memória simultaneamente. (instanciação lado a lado) sem conflitos.
Como criar shared assemblies ?
Crie o código fonte do seu arquivo DLL/EXE
Gere o nome de assembly único usando o utilitário SN (Microsoft .NET Strong Name Utility)
Assine seu arquivo DLL/EXE com a chave privada modificando o arquivo AssemblyInfo
Compile seu arquivo DLL/EXE
Coloco arquivo compilado no Global Assembly Cache usando o utilitário gacUtil (Microsoft .NET Assembly Cache Utility)
Como criar um nome único para o assembly ?
A Microsoft usa um par de chaves pública e privada para identificar de forma única um assembly. Estas chaves são geradas usando o utilitário SN.exe ( procure na pasta X:\Arquivos de programas\Microsoft Visual Studio .NET\FrameworkSDK\Bin ) . A sintaxe comum é :
sn -k MeuArquivoDeChaves.snk
Onde : K indica que queremos gerar uma chave e MeuArquivoDeChaves.key é o nome do arquivo onde a chave vai estar armazenada.
Como assinar o arquivo DLL/EXE ?
Antes de colocar o assembly no GAC você precisa assiná-lo usando as chaves geradas. Você referencia a informação da assinatura em arquivo especial chamado AssemblyInfo.vb Você deve acrescentar uma linha que se pareça com a seguinte : <Assembly : AssemblyKeyFile(" c:\KeyFiles\MeuArquivoDeChaves.snk ") >
Na próxima vez que você compilar o projeto , as informações de chave serão incluídas no grupo.
Como instalar o assembly no GAC ?
Existem diversas formas de você instalar o assembly no GAC. Você pode usar o utilitário GACUtil.exe ( procure na pasta X:\Arquivos de programas\Microsoft Visual Studio .NET\FrameworkSDK\Bin ou pode arrastar e soltar o assembly usando o plug-in WIndows Explorer. A estrutura especial de diretório é criada automaticamente para você e seu assembly deverá aparecer na lista do GAC.
A vantagem de colocar assemblies no GAC é que o desempenho fica otimizado pois o runtime os localiza de forma mais rápida sem ter que verificar a segurança a cada carga do assembly.
E vou ficando por aqui. Espero que esta pequena introdução o ajude a compreender melhor os assemblies.
Aguarde mais artigos sobre o assunto ..