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:
- Creare un assembly con nome sicuro con un'interfaccia pubblica contenente informazioni sul tipo che possono essere incorporate.
- Creare un assembly di runtime con nome sicuro che implementa l'interfaccia pubblica.
- Creare un programma client che incorpora le informazioni sul tipo dell'interfaccia pubblica e crea un'istanza della classe dall'assembly di runtime.
- Modificare e ricompilare l'assembly di runtime.
- 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 eGuid
attributi con GUID univoci. - L'assembly viene annotato con l'attributo
ImportedFromTypeLib
o l'attributoPrimaryInteropAssembly
e un attributoGuid
a livello di assembly. I modelli di progetto Visual C# e Visual Basic includono un attributo a livelloGuid
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.
In Visual Studio selezionare File>Nuovo>Progetto.
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.
Nella finestra di dialogo Configura il nuovo progetto digitare TypeEquivalenceInterface in Nome progetto e quindi selezionare Crea. Viene creato il nuovo progetto.
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 Sì al prompt per rinominare anche la classe in
ISampleInterface
. Questa classe rappresenta l'interfaccia pubblica per la classe .In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto TypeEquivalenceInterface e quindi scegliere Proprietà.
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.
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.
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.
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
Nel menu Strumenti selezionare Crea GUID e nella finestra di dialogo Crea GUID selezionare Formato registro. Selezionare Copia e quindi Esci.
Nell'attributo
Guid
del codice sostituire il GUID di esempio con il GUID copiato e rimuovere le parentesi graffe ({ }).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("")>
Selezionare Salva>tutto o premere CTRL+MAIUSC+S per salvare i file e il progetto.
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.
In Visual Studio selezionare File>Nuovo>Progetto.
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.
Nella finestra di dialogo Configura il nuovo progetto digitare TypeEquivalenceRuntime in Nome progetto e quindi selezionare Crea. Viene creato il nuovo progetto.
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 Sì al prompt per rinominare anche la classe in
SampleClass
. Questa classe implementa l'interfacciaISampleInterface
.In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto TypeEquivalenceInterface e scegliere Proprietà.
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.
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.
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.
In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto TypeEquivalenceRuntime e scegliere Aggiungi>riferimento.
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.
In Esplora soluzioni espandere la cartella Riferimenti e selezionare il riferimento TypeEquivalenceInterface. Nel riquadro Proprietà impostare Versione specifica su False se non è già presente.
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
Selezionare Salva>tutto o premere CTRL+MAIUSC+S per salvare i file e il progetto.
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.
In Visual Studio selezionare File>Nuovo>Progetto.
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.
Nella finestra di dialogo Configura il nuovo progetto , in Nome progetto digitare TypeEquivalenceClient e quindi selezionare Crea. Viene creato il nuovo progetto.
In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto TypeEquivalenceClient e scegliere Proprietà.
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.
In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto TypeEquivalenceClient e scegliere Aggiungi>riferimento.
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.
In Esplora soluzioni espandere la cartella Riferimenti e selezionare il riferimento TypeEquivalenceInterface. Nel riquadro Proprietà impostare Incorpora tipi di interoperabilità su True.
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
Selezionare Salva>tutto o premere CTRL+MAIUSC+S per salvare i file e il progetto.
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.
In VisualStudio selezionare Apriprogetto/soluzione file >> e aprire il progetto TypeEquivalenceInterface.
In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto TypeEquivalenceInterface e scegliere Proprietà.
Selezionare Applicazione nel riquadro sinistro della schermata Proprietà e quindi selezionare Informazioni assembly.
Nella finestra di dialogo Informazioni assembly modificare i valori Versione assembly e Versione filein 2.0.0.0 e quindi selezionare OK.
Aprire il file SampleInterface.cs o SampleInterface.vb e aggiungere la riga di codice seguente all'interfaccia
ISampleInterface
:DateTime GetDate();
Function GetDate() As Date
Selezionare Salva>tutto o premere CTRL+MAIUSC+S per salvare i file e il progetto.
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.
In Visual Studio selezionare File>Apri>progetto/soluzione e aprire il progetto TypeEquivalenceRuntime .
In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto TypeEquivalenceRuntime e scegliere Proprietà.
Selezionare Applicazione nel riquadro sinistro della schermata Proprietà e quindi selezionare Informazioni assembly.
Nella finestra di dialogo Informazioni assembly modificare i valori Versione assembly e Versione filein 2.0.0.0 e quindi selezionare OK.
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
Selezionare Salva>tutto o premere CTRL+MAIUSC+S per salvare i file e il progetto.
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.