Procedura dettagliata: Incorporare i tipi da assembly gestiti in Visual Studio

Se si incorporano informazioni sul tipo da un assembly gestito con nome sicuro, è possibile effettuare un accoppiamento debole dei tipi in un'applicazione per ottenere l'indipendenza dalla versione. Ovvero, il programma può essere scritto per usare i tipi di qualsiasi versione di una libreria gestita senza dover essere ricompilati per ogni nuova versione.

L'incorporamento dei tipi viene spesso usato con l'interoperabilità COM, ad esempio nel caso di un'applicazione che usa gli oggetti di automazione di Microsoft Office. L'incorporamento di informazioni sul tipo consente alla stessa build di un programma di funzionare con versioni diverse di Microsoft Office in computer diversi. Tuttavia, è anche possibile usare l'incorporamento dei tipi con soluzioni completamente gestite.

Dopo aver specificato le interfacce pubbliche che possono essere incorporate, è possibile creare classi di runtime che implementano tali interfacce. Un programma client può incorporare le informazioni sul tipo per le interfacce in fase di progettazione facendo riferimento all'assembly che contiene le interfacce pubbliche e impostando la Embed Interop Types proprietà del riferimento su True. Il programma client può quindi caricare le istanze degli oggetti di runtime digitati come tali interfacce. Equivale a usare il compilatore della riga di comando e fare riferimento all'assembly usando l'opzione del compilatore EmbedInteropTypes.

Se si crea una nuova versione dell'assembly di runtime con nome sicuro, il programma client non deve essere ricompilato. Il programma client continua a usare qualsiasi versione dell'assembly di runtime sia disponibile, usando le informazioni sul tipo incorporato per le interfacce pubbliche.

Questa procedura dettagliata è costituita dai passaggi seguenti:

  1. Creare un assembly con nome sicuro con un'interfaccia pubblica contenente informazioni sul tipo che possono essere incorporate.
  2. Creare un assembly di runtime con nome sicuro che implementa l'interfaccia pubblica.
  3. Creare un programma client che incorpora le informazioni sul tipo dell'interfaccia pubblica e crea un'istanza della classe dall'assembly di runtime.
  4. Modificare e ricompilare l'assembly di runtime.
  5. Eseguire il programma client per verificare che usi la nuova versione dell'assembly di runtime senza dover essere ricompilata.

Nota

Nomi o percorsi visualizzati per alcuni elementi dell'interfaccia utente di Visual Studio nelle istruzioni seguenti potrebbero essere diversi nel computer in uso. La versione di Visual Studio in uso e le impostazioni configurate determinano questi elementi. Per altre informazioni, vedere Personalizzazione dell'IDE.

Condizioni e limitazioni

È possibile incorporare le informazioni sul tipo da un assembly nelle condizioni seguenti:

  • L'assembly espone almeno un'interfaccia pubblica.
  • Le interfacce incorporate vengono annotate con ComImport attributi e Guid attributi con GUID univoci.
  • L'assembly viene annotato con l'attributo ImportedFromTypeLib o l'attributo PrimaryInteropAssembly e un attributo Guid a livello di assembly. I modelli di progetto Visual C# e Visual Basic includono un attributo a livello Guid di assembly per impostazione predefinita.

Poiché la funzione primaria di incorporamento dei tipi consiste nel supportare gli assembly di interoperabilità COM, si applicano le limitazioni seguenti quando si incorporano le informazioni sul tipo in una soluzione completamente gestita:

  • Solo gli attributi specifici dell'interoperabilità COM sono incorporati. Altri attributi vengono ignorati.
  • Se un tipo usa parametri generici e il tipo del parametro generico è un tipo incorporato, tale tipo non può essere usato attraverso un limite di assembly. Esempi di superamento di un limite di assembly includono la chiamata di un metodo da un altro assembly o la derivazione di un tipo da un tipo definito in un altro assembly.
  • Le costanti non vengono incorporate.
  • La classe System.Collections.Generic.Dictionary<TKey,TValue> non supporta un tipo incorporato come chiave. È possibile implementare un proprio tipo di dizionario per supportare un tipo incorporato come chiave.

Creare un'interfaccia

Il primo passaggio consiste nel creare l'assembly dell'interfaccia di equivalenza del tipo.

  1. In Visual Studio selezionare File>Nuovo>Progetto.

  2. Nella finestra di dialogo Crea un nuovo progetto digitare libreria di classi nella casella Cerca modelli . Selezionare il modello C# o Visual Basic Class Library (.NET Framework) dall'elenco e quindi selezionare Avanti.

  3. Nella finestra di dialogo Configura il nuovo progetto digitare TypeEquivalenceInterface in Nome progetto e quindi selezionare Crea. Viene creato il nuovo progetto.

  4. In Esplora soluzioni fare clic con il pulsante destro del mouse sul file Class1.cs o Class1.vb, scegliere Rinomina e rinominare il file da Class1 a ISampleInterface. Rispondere al prompt per rinominare anche la classe in ISampleInterface. Questa classe rappresenta l'interfaccia pubblica per la classe .

  5. In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto TypeEquivalenceInterface e quindi scegliere Proprietà.

  6. Selezionare Compila nel riquadro sinistro della schermata Proprietà e impostare il percorso di output su un percorso nel computer, ad esempio C:\TypeEquivalenceSample. In questa procedura dettagliata viene usata la stessa posizione.

  7. Selezionare Crea>denominazione complessa nel riquadro sinistro della schermata Proprietà e quindi selezionare la casella di controllo Firma assembly . Nel file chiave con nome sicuro selezionare Sfoglia.

  8. Passare a e selezionare il file key.snk creato nel progetto TypeEquivalenceInterface e quindi selezionare OK. Per altre informazioni, vedere Creare una coppia di chiavi pubblica-privata.

  9. Aprire il file di classe ISampleInterface nell'editor di codice e sostituirlo con il codice seguente per creare l'interfaccia 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
    
  10. Nel menu Strumenti selezionare Crea GUID e nella finestra di dialogo Crea GUID selezionare Formato registro. Selezionare Copia e quindi Esci.

  11. Nell'attributo Guid del codice sostituire il GUID di esempio con il GUID copiato e rimuovere le parentesi graffe ({ }).

  12. In Esplora soluzioni espandere la cartella Proprietà e selezionare il file AssemblyInfo.cs o AssemblyInfo.vb. Nell'editor di codice aggiungere l'attributo seguente al file:

    [assembly: ImportedFromTypeLib("")]
    
    <Assembly: ImportedFromTypeLib("")>
    
  13. Selezionare Salva>tutto o premere CTRL+MAIUSC+S per salvare i file e il progetto.

  14. In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto TypeEquivalenceInterface e scegliere Compila. Il file DLL della libreria di classi viene compilato e salvato nel percorso di output di compilazione specificato, ad esempio C:\TypeEquivalenceSample.

Creare una classe di runtime

Creare quindi la classe di runtime di equivalenza del tipo.

  1. In Visual Studio selezionare File>Nuovo>Progetto.

  2. Nella finestra di dialogo Crea un nuovo progetto digitare libreria di classi nella casella Cerca modelli . Selezionare il modello C# o Visual Basic Class Library (.NET Framework) dall'elenco e quindi selezionare Avanti.

  3. Nella finestra di dialogo Configura il nuovo progetto digitare TypeEquivalenceRuntime in Nome progetto e quindi selezionare Crea. Viene creato il nuovo progetto.

  4. In Esplora soluzioni fare clic con il pulsante destro del mouse sul file Class1.cs o Class1.vb, scegliere Rinomina e rinominare il file da Class1 a SampleClass. Rispondere al prompt per rinominare anche la classe in SampleClass. Questa classe implementa l'interfaccia ISampleInterface .

  5. In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto TypeEquivalenceInterface e scegliere Proprietà.

  6. Selezionare Compila nel riquadro sinistro della schermata Proprietà e quindi impostare il percorso di output sulla stessa posizione usata per il progetto TypeEquivalenceInterface , ad esempio C:\TypeEquivalenceSample.

  7. Selezionare Crea>denominazione complessa nel riquadro sinistro della schermata Proprietà e quindi selezionare la casella di controllo Firma assembly . Nel file chiave con nome sicuro selezionare Sfoglia.

  8. Passare a e selezionare il file key.snk creato nel progetto TypeEquivalenceInterface e quindi selezionare OK. Per altre informazioni, vedere Creare una coppia di chiavi pubblica-privata.

  9. In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto TypeEquivalenceRuntime e scegliere Aggiungi>riferimento.

  10. Nella finestra di dialogo Gestione riferimenti selezionare Sfoglia e passare alla cartella del percorso di output. Selezionare il fileTypeEquivalenceInterface.dll, selezionare Aggiungi e quindi ok.

  11. In Esplora soluzioni espandere la cartella Riferimenti e selezionare il riferimento TypeEquivalenceInterface. Nel riquadro Proprietà impostare Versione specifica su False se non è già presente.

  12. Aprire il file di classe SampleClass nell'editor di codice e sostituirlo con il codice seguente per creare la SampleClass classe:

    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
    
  13. Selezionare Salva>tutto o premere CTRL+MAIUSC+S per salvare i file e il progetto.

  14. In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto TypeEquivalenceRuntime e scegliere Compila. Il file DLL della libreria di classi viene compilato e salvato nel percorso di output di compilazione specificato.

Creare un progetto client

Creare infine un programma client di equivalenza del tipo che fa riferimento all'assembly dell'interfaccia.

  1. In Visual Studio selezionare File>Nuovo>Progetto.

  2. Nella finestra di dialogo Crea un nuovo progetto digitare console nella casella Cerca modelli . Selezionare il modello C# o Visual Basic Console App (.NET Framework) dall'elenco e quindi selezionare Avanti.

  3. Nella finestra di dialogo Configura il nuovo progetto , in Nome progetto digitare TypeEquivalenceClient e quindi selezionare Crea. Viene creato il nuovo progetto.

  4. In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto TypeEquivalenceClient e scegliere Proprietà.

  5. Selezionare Compila nel riquadro sinistro della schermata Proprietà e quindi impostare il percorso di output sulla stessa posizione usata per il progetto TypeEquivalenceInterface, ad esempio C:\TypeEquivalenceSample.

  6. In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto TypeEquivalenceClient e scegliere Aggiungi>riferimento.

  7. Nella finestra di dialogo Gestione riferimenti , se il file diTypeEquivalenceInterface.dll è già elencato, selezionarlo. In caso contrario, selezionare Sfoglia, passare alla cartella del percorso di output, selezionare il file TypeEquivalenceInterface.dll (non il TypeEquivalenceRuntime.dll) e selezionare Aggiungi. Selezionare OK.

  8. In Esplora soluzioni espandere la cartella Riferimenti e selezionare il riferimento TypeEquivalenceInterface. Nel riquadro Proprietà impostare Incorpora tipi di interoperabilità su True.

  9. Aprire il file Program.cs o Module1.vb nell'editor di codice e sostituirlo con il codice seguente per creare il programma client:

    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
    
  10. Selezionare Salva>tutto o premere CTRL+MAIUSC+S per salvare i file e il progetto.

  11. Premere CTRL+F5 per compilare ed eseguire il programma. Si noti che l'output della console restituisce l'assembly versione 1.0.0.0.

Modificare l'interfaccia

Modificare ora l'assembly di interfaccia e modificarne la versione.

  1. In VisualStudio selezionare Apriprogetto/soluzione file >> e aprire il progetto TypeEquivalenceInterface.

  2. In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto TypeEquivalenceInterface e scegliere Proprietà.

  3. Selezionare Applicazione nel riquadro sinistro della schermata Proprietà e quindi selezionare Informazioni assembly.

  4. Nella finestra di dialogo Informazioni assembly modificare i valori Versione assembly e Versione filein 2.0.0.0 e quindi selezionare OK.

  5. Aprire il file SampleInterface.cs o SampleInterface.vb e aggiungere la riga di codice seguente all'interfaccia ISampleInterface :

    DateTime GetDate();
    
    Function GetDate() As Date
    
  6. Selezionare Salva>tutto o premere CTRL+MAIUSC+S per salvare i file e il progetto.

  7. In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto TypeEquivalenceInterface e scegliere Compila. Una nuova versione del file DLL della libreria di classi viene compilata e salvata nel percorso di output della compilazione.

Modificare la classe di runtime

Modificare anche la classe di runtime e aggiornarne la versione.

  1. In Visual Studio selezionare File>Apri>progetto/soluzione e aprire il progetto TypeEquivalenceRuntime .

  2. In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto TypeEquivalenceRuntime e scegliere Proprietà.

  3. Selezionare Applicazione nel riquadro sinistro della schermata Proprietà e quindi selezionare Informazioni assembly.

  4. Nella finestra di dialogo Informazioni assembly modificare i valori Versione assembly e Versione filein 2.0.0.0 e quindi selezionare OK.

  5. Aprire il file SampleClass.cs o SampleClass.vb e aggiungere il codice seguente alla SampleClass classe :

     public DateTime GetDate()
     {
         return DateTime.Now;
     }
    
    Public Function GetDate() As DateTime Implements ISampleInterface.GetDate
        Return Now
    End Function
    
  6. Selezionare Salva>tutto o premere CTRL+MAIUSC+S per salvare i file e il progetto.

  7. In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto TypeEquivalenceRuntime e scegliere Compila. Una nuova versione del file DLL della libreria di classi viene compilata e salvata nel percorso di output della compilazione.

Eseguire il programma client aggiornato

Passare al percorso della cartella di output della compilazione ed eseguire TypeEquivalenceClient.exe. Si noti che l'output della console riflette ora la nuova versione dell'assembly TypeEquivalenceRuntime, 2.0.0.0, senza ricompilare il programma.

Vedi anche