Passo a passo: Inserir tipos de assemblies gerenciados no Visual Studio
Se você inserir informações de um assembly gerenciado de nome forte, você poderá acoplar vagamente tipos em um aplicativo para atingir a independência de versão. Isto é, seu programa pode ser escrito para usar tipos de qualquer versão de uma biblioteca gerenciada sem precisar ser recompilado para cada versão nova.
A incorporação de tipo é frequentemente usada com a interoperabilidade COM, como um aplicativo que usa objetos de automação do Microsoft Office. Inserir informações de tipo permite que o mesmo build de um programa funcione com diferentes versões do Microsoft Office em diferentes computadores. No entanto, você também pode usar a inserção de tipo com uma solução totalmente gerenciada.
Depois de especificar as interfaces públicas que podem ser inseridas, crie classes de runtime que implementam essas interfaces. Um programa cliente pode inserir as informações de tipo para essas interfaces em tempo de design referenciando o assembly que contém as interfaces públicas e configurando a propriedade Embed Interop Types
da referência como True
. O programa cliente pode, então, carregar instâncias dos objetos de runtime de tipo como essas interfaces. Isso é equivalente a usar o compilador de linha de comando e fazer referência ao assembly usando a opção do compilador EmbedInteropTypes.
Se você criar uma nova versão do seu assembly de runtime de nome forte, o programa cliente não precisará ser recompilado. O programa cliente continua a usar qualquer versão do assembly em runtime que está disponível para ele, usando as informações de tipo inseridas para as interfaces públicas.
Neste passo a passo, você vai:
- Criar um assembly de nome forte com uma interface pública que contém informações de tipo que podem ser inseridas.
- Criar um assembly de runtime de nome forte que implementa a interface pública.
- Criará um programa cliente que insere as informações de tipo da interface pública e criará uma instância da classe do assembly de runtime.
- Modificará e recompilará o assembly de runtime.
- Executar o programa cliente para garantir o uso da nova versão do assembly de runtime sem a necessidade de recompilá-lo.
Observação
Seu computador pode mostrar diferentes nomes ou locais para alguns dos elementos de interface do usuário do Visual Studio nas instruções a seguir. A edição do Visual Studio que você possui e as configurações que você usa determinam esses elementos. Para obter mais informações, consulte Personalizando o IDE.
Condições e limitações
Você pode inserir informações de tipo de um assembly nas seguintes condições:
- O assembly expõe pelo menos uma interface pública.
- As interfaces inseridas são anotadas com atributos
ComImport
e atributosGuid
com GUIDs exclusivos. - O assembly é anotado com o atributo
ImportedFromTypeLib
ou o atributoPrimaryInteropAssembly
e um atributoGuid
de nível do assembly. Os modelos de projeto do Visual C# e do Visual Basic incluem por padrão um atributoGuid
no nível do assembly.
Como a principal função da inserção de tipo é dar suporte a assemblies de interoperabilidade COM, as limitações a seguir se aplicam ao inserir informações de tipo em uma solução totalmente gerenciada:
- Somente os atributos específicos à interoperabilidade COM são inseridos. Os outros atributos são ignorados.
- Se um tipo usar parâmetros genéricos e o tipo de parâmetro genérico for um tipo inserido, esse tipo não poderá ser usado em um limite de assembly. Os exemplos de cruzar um limite de assembly incluem chamar um método de outro assembly ou derivar um tipo de um tipo definido em outro assembly.
- Constantes não são inseridas.
- A classe System.Collections.Generic.Dictionary<TKey,TValue> não dá suporte a um tipo inserido como uma chave. Você pode implementar seu próprio tipo de dicionário para dar suporte a um tipo inserido como uma chave.
Criar uma interface
A primeira etapa é criar o assembly de interface de equivalência do tipo.
No Visual Studio, selecione Arquivo>Novo>Projeto.
Na caixa de diálogo Criar um novo projeto, digite a biblioteca de classes na caixa Pesquisar modelos. Selecione o modelo de biblioteca de classes (.NET Framework) C# ou Visual Basic na lista e selecione Avançar.
Na caixa de diálogo Configurar seu novo projeto, em Nome do projeto, digite TypeEquivalenceInterface e selecione Criar. Quando um novo projeto é criado.
Em Gerenciador de Soluções, clique com o botão direito no arquivo Class1.cs ou Class1.vb, selecione Renomear e renomeie o arquivo de Class1 para ISampleInterface. Responda Sim ao prompt para renomear também a classe para
ISampleInterface
. Essa classe representará a interface pública para a classe.No Gerenciador de Soluções, clique com o botão direito no projeto TypeEquivalenceInterface e selecione Propriedades.
Selecione Compilar no painel esquerdo da tela Propriedades e defina o Caminho de saída como um local no computador, por exemplo, C:\TypeEquivalenceSample. Você usará o mesmo local ao longo deste passo a passo.
Selecione Build>Strong nomeando no painel esquerdo da tela Propriedades e, em seguida, marque a caixa de seleção Assinar o assembly. Em Strong name key file, selecione Browse.
Navegue até e selecione o arquivo key.snk que você criou no projeto TypeEquivalenceInterface e selecione OK. Para obter mais informações, confira Criar um par de chaves pública-privada.
Abra o arquivo de classe ISampleInterface no editor de código e substitua o conteúdo pelo seguinte código para criar a interface
ISampleInterface
:using System; using System.Runtime.InteropServices; namespace TypeEquivalenceInterface { [ComImport] [Guid("8DA56996-A151-4136-B474-32784559F6DF")] public interface ISampleInterface { void GetUserInput(); string UserInput { get; } } }
Imports System.Runtime.InteropServices <ComImport()> <Guid("8DA56996-A151-4136-B474-32784559F6DF")> Public Interface ISampleInterface Sub GetUserInput() ReadOnly Property UserInput As String End Interface
No menu Ferramentas, selecione Criar Guide, na caixa de diálogo Criar GUID, selecione o Formato do Registro. Selecione Copiar e, em seguida, selecione Sair.
No atributo
Guid
do código, substitua o GUID de exemplo pelo GUID copiado e remova as chaves ({ }).Em Gerenciador de Soluções, expanda a pasta Propriedades e selecione o arquivo AssemblyInfo.cs ou AssemblyInfo.vb. No editor de códigos, adicione o seguinte atributo ao arquivo:
[assembly: ImportedFromTypeLib("")]
<Assembly: ImportedFromTypeLib("")>
Selecione Arquivo>Salvar Tudo ou pressione Ctrl+Shift+S para salvar os arquivos e o projeto.
No Gerenciador de Soluções, clique com o botão direito no projeto TypeEquivalenceInterface e selecione Compilar. O arquivo .dll da biblioteca de classes é compilado e salvo no caminho de saída de build especificado, por exemplo, C:\TypeEquivalenceSample.
Criar uma classe de runtime
Em seguida, crie a classe de runtime de equivalência de tipo.
No Visual Studio, selecione Arquivo>Novo>Projeto.
Na caixa de diálogo Criar um novo projeto, digite a biblioteca de classes na caixa Pesquisar modelos. Selecione o modelo de biblioteca de classes (.NET Framework) C# ou Visual Basic na lista e selecione Avançar.
Na caixa de diálogo Configurar seu novo projeto, em Nome do projeto, digite TypeEquivalenceRuntime e selecione Criar. Quando um novo projeto é criado.
Em Gerenciador de Soluções, clique com o botão direito no arquivo Class1.cs ou Class1.vb, selecione Renomear e renomeie o arquivo de Class1 para SampleClass. Responda Sim ao prompt para renomear também a classe para
SampleClass
. Essa classe implementa a interfaceISampleInterface
.No Gerenciador de Soluções, clique com o botão direito no projeto TypeEquivalenceInterface e selecione Propriedades.
Selecione Compilar no painel esquerdo da tela Propriedades e defina o Caminho de saída como o mesmo local usado para o projeto TypeEquivalenceInterface, por exemplo, C:\TypeEquivalenceSample.
Selecione Build>Strong nomeando no painel esquerdo da tela Propriedades e, em seguida, marque a caixa de seleção Assinar o assembly. Em Strong name key file, selecione Browse.
Navegue até e selecione o arquivo key.snk que você criou no projeto TypeEquivalenceInterface e selecione OK. Para obter mais informações, confira Criar um par de chaves pública-privada.
No Gerenciador de Soluções, clique com o botão direito no projeto TypeEquivalenceRuntime e selecione Adicionar>Referência.
Na caixa de diálogo Gerenciador de Referência, selecione Procurar e navegue até a pasta de caminho de saída. Selecione o arquivo TypeEquivalenceInterface.dll, selecione Adicionar e selecione OK.
Em Gerenciador de Soluções, expanda a pasta Referências e selecione a referência TypeEquivalenceInterface. No painel Propriedades, defina Versão Específica como Falso se ainda não tiver feito isso.
Abra o arquivo de classe SampleClass no editor de código e substitua o conteúdo pelo seguinte código para criar a classe
SampleClass
:using System; using TypeEquivalenceInterface; namespace TypeEquivalenceRuntime { public class SampleClass : ISampleInterface { private string p_UserInput; public string UserInput { get { return p_UserInput; } } public void GetUserInput() { Console.WriteLine("Please enter a value:"); p_UserInput = Console.ReadLine(); } } }
Imports TypeEquivalenceInterface Public Class SampleClass Implements ISampleInterface Private p_UserInput As String Public ReadOnly Property UserInput() As String Implements ISampleInterface.UserInput Get Return p_UserInput End Get End Property Public Sub GetUserInput() Implements ISampleInterface.GetUserInput Console.WriteLine("Please enter a value:") p_UserInput = Console.ReadLine() End Sub End Class
Selecione Arquivo>Salvar Tudo ou pressione Ctrl+Shift+S para salvar os arquivos e o projeto.
No Gerenciador de Soluções, clique com o botão direito no projeto TypeEquivalenceRuntime e selecione Compilar. O arquivo DLL da biblioteca de classes é compilado e salvo no caminho de saída de build especificado.
Criar um projeto de cliente
Por fim, crie um programa cliente de equivalência de tipo que faça referência ao assembly de interface.
No Visual Studio, selecione Arquivo>Novo>Projeto.
Na caixa de diálogo Criar um novo projeto, digite console na caixa Pesquisar modelos. Selecione o modelo de Aplicativo de console (.NET Framework) C# ou Visual Basic na lista e selecione Avançar.
Na caixa de diálogo Configurar seu novo projeto, em Nome do projeto, digite TypeEquivalenceClient e selecione Criar. Quando um novo projeto é criado.
No Gerenciador de Soluções, clique com o botão direito no projeto TypeEquivalenceClient e selecione Propriedades.
Selecione Compilar no painel esquerdo da tela Propriedades e defina o Caminho de saída como o mesmo local usado para o projeto TypeEquivalenceInterface, por exemplo, C:\TypeEquivalenceSample.
No Gerenciador de Soluções, clique com o botão direito no projeto TypeEquivalenceClient e selecione Adicionar>Referência.
Na caixa de diálogo Gerenciador de Referência, se o arquivo TypeEquivalenceInterface.dll já estiver listado, selecione-o. Caso contrário, selecione Procurar, navegue até a pasta de caminho de saída, selecione o arquivo TypeEquivalenceInterface.dll (não o TypeEquivalenceRuntime.dll) e selecione Adicionar. Selecione OK.
Em Gerenciador de Soluções, expanda a pasta Referências e selecione a referência TypeEquivalenceInterface. No painel Propriedades, defina Inserir Tipos de Interoperação como Verdadeiro.
Abra o arquivo Program.cs ou Module1.vb no editor de código e substitua seu conteúdo pelo seguinte código para criar o programa cliente:
using System; using System.Reflection; using TypeEquivalenceInterface; namespace TypeEquivalenceClient { class Program { static void Main(string[] args) { Assembly sampleAssembly = Assembly.Load("TypeEquivalenceRuntime"); ISampleInterface sampleClass = (ISampleInterface)sampleAssembly.CreateInstance("TypeEquivalenceRuntime.SampleClass"); sampleClass.GetUserInput(); Console.WriteLine(sampleClass.UserInput); Console.WriteLine(sampleAssembly.GetName().Version.ToString()); Console.ReadLine(); } } }
Imports System.Reflection Imports TypeEquivalenceInterface Module Module1 Sub Main() Dim sampleAssembly = Assembly.Load("TypeEquivalenceRuntime") Dim sampleClass As ISampleInterface = CType( _ sampleAssembly.CreateInstance("TypeEquivalenceRuntime.SampleClass"), ISampleInterface) sampleClass.GetUserInput() Console.WriteLine(sampleClass.UserInput) Console.WriteLine(sampleAssembly.GetName().Version) Console.ReadLine() End Sub End Module
Selecione Arquivo>Salvar Tudo ou pressione Ctrl+Shift+S para salvar os arquivos e o projeto.
Pressione Ctrl+F5 para compilar e executar o programa. Observe que a saída do console retorna o assembly versão 1.0.0.0.
Modificar a interface
Agora, modifique o assembly da interface e altere sua versão.
No Visual Studio, selecione Arquivo>Abrir>Projeto/Solução e abra o projeto TypeEquivalenceInterface.
No Gerenciador de Soluções, clique com o botão direito no projeto TypeEquivalenceInterface e selecione Propriedades.
Selecione Aplicativo no painel esquerdo da tela Propriedades e selecione Informações do Assembly.
Na caixa de diálogo Informações do Assembly, altere os valores de Versão do assembly e Versão do arquivo para 2.0.0.0 e selecione OK.
Abra o arquivo SampleInterface.cs ou SampleInterface.vb e adicione a seguinte linha de código à interface
ISampleInterface
:DateTime GetDate();
Function GetDate() As Date
Selecione Arquivo>Salvar Tudo ou pressione Ctrl+Shift+S para salvar os arquivos e o projeto.
No Gerenciador de Soluções, clique com o botão direito no projeto TypeEquivalenceInterface e selecione Compilar. Uma nova versão do arquivo DLL da biblioteca de classes é compilado e salvo no caminho de saída do build.
Modificar a classe de runtime
Modifique também a classe de runtime e atualize sua versão.
No Visual Studio, selecione Arquivo>Abrir>Projeto/Solução e abra o projeto TypeEquivalenceRuntime.
No Gerenciador de Soluções, clique com o botão direito no projeto TypeEquivalenceRuntime e selecione Propriedades.
Selecione Aplicativo no painel esquerdo da tela Propriedades e selecione Informações do Assembly.
Na caixa de diálogo Informações do Assembly, altere os valores de Versão do assembly e Versão do arquivo para 2.0.0.0 e selecione OK.
Abra o arquivo SampleClass.cs ou SampleClass.vb, e adicione o seguinte código à classe
SampleClass
:public DateTime GetDate() { return DateTime.Now; }
Public Function GetDate() As DateTime Implements ISampleInterface.GetDate Return Now End Function
Selecione Arquivo>Salvar Tudo ou pressione Ctrl+Shift+S para salvar os arquivos e o projeto.
No Gerenciador de Soluções, clique com o botão direito no projeto TypeEquivalenceRuntime e selecione Compilar. Uma nova versão do arquivo DLL da biblioteca de classes é compilado e salvo no caminho de saída do build.
Executar o programa cliente atualizado
Vá para o local da pasta de saída do build e execute TypeEquivalenceClient.exe. Observe que a saída do console agora reflete a nova versão do assembly TypeEquivalenceRuntime
, 2.0.0.0, sem que o programa seja recompilado.