Exemplarische Vorgehensweise: Einbetten von Typen aus verwalteten Assemblys (C# und Visual Basic)

Wenn Sie Typinformationen von einer verwalteten Assembly mit starkem Namen einbetten, können Sie Typen in einer Anwendung lose verknüpfen, um Versionsunabhängigkeit zu erreichen.Ihr Programm kann daher für Typen aus unterschiedlichen Versionen einer verwalteten Bibliothek geschrieben werden; eine Neukompilierung für jede Version ist nicht erforderlich.

Die Typeinbettung wird häufig von COM-Interop verwendet, beispielsweise eine Anwendung, die Automatisierungsobjekte von Microsoft Office verwendet.Mithilfe von eingebetteten Typinformationen kann der gleiche Build eines Programms mit verschiedenen Versionen von Microsoft Office auf unterschiedlichen Computern verwendet werden.Sie können die Typeinbettung jedoch auch mit einer vollständig verwalteten Lösung verwenden.

Typinformationen können aus Assemblys eingebettet werden, die über folgende Eigenschaften verfügen:

  • Die Assembly macht mindestens eine öffentliche Schnittstelle verfügbar.

  • Die eingebetteten Schnittstellen werden mit einem ComImport-Attribut und einem Guid-Attribut (sowie einer eindeutigen GUID) gekennzeichnet.

  • Die Assembly wird mit dem ImportedFromTypeLib-Attribut oder dem PrimaryInteropAssembly-Attribut sowie einem Guid-Attribut auf Assemblyebene gekennzeichnet.(Visual Basic- und Visual C#-Projektvorlagen enthalten standardmäßig ein Guid-Attribut auf Assemblyebene.)

Nachdem Sie die öffentlichen Schnittstellen angegeben haben, die eingebettet werden können, können Sie Laufzeitklassen erstellen, die diese Schnittstellen implementieren.Zur Laufzeit können die Typinformationen für diese Schnittstellen dann von einem Clientprogramm eingebettet werden, indem auf die Assembly mit den öffentlichen Schnittstellen verwiesen und die Embed Interop Types-Eigenschaft des Verweises auf True festgelegt wird.Dies entspricht dem Verwenden des Befehlszeilencompilers und dem Verweisen auf die Assembly mit der /link-Compileroption.Instanzen der Laufzeitobjekte, die als entsprechende Schnittstellen typisiert wurden, können daraufhin vom Clientprogramm geladen werden.Wenn Sie eine neue Version der Laufzeitassembly mit starkem Namen erstellen, muss das Clientprogramm mit der aktualisierten Laufzeitassembly nicht neu kompiliert werden.Das Clientprogramm verwendet stattdessen weiterhin die jeweils verfügbare Version der Laufzeitassembly mit den eingebetteten Typinformationen für die öffentlichen Schnittstellen.

Da die primäre Funktion der Typeinbettung das Einbetten von Typinformationen von COM-Interop-Assemblys ist, gelten die folgenden Einschränkungen, wenn Sie Typinformationen in eine vollständig verwaltete Projektmappe einbetten:

  • Nur für COM-Interop spezifische Attribute werden eingebettet; andere Attribute werden ignoriert.

  • Wenn ein Typ generische Parameter verwendet, und der Typ des generischen Parameters ein eingebetteter Typ ist, kann dieser Typ nicht über eine Assemblygrenze hinweg verwendet werden.Beispiele für das Überschreiten einer Assemblygrenze sind das Aufrufen einer Methode in einer anderen Assembly oder das Ableiten eines Typs von einem in einer anderen Assembly definierten Typ.

  • Konstanten werden nicht eingebettet.

  • Die System.Collections.Generic.Dictionary<TKey, TValue>-Klasse unterstützt keinen eingebetteten Typ als Schlüssel.Sie können einen eigenen Wörterbuchtyp implementieren, um einen eingebetteten Typ als Schlüssel zu unterstützen.

In dieser exemplarischen Vorgehensweise führen Sie Folgendes aus:

  • Erstellen Sie eine Assembly mit starkem Namen, die eine öffentliche Schnittstelle mit Typinformationen aufweist, die eingebettet werden können.

  • Erstellen Sie eine Laufzeitassembly mit starkem Namen, die diese öffentliche Schnittstelle implementiert.

  • Erstellen Sie ein Clientprogramm, das die Typinformationen aus der öffentlichen Schnittstelle einbettet und eine Instanz der Klasse aus der Laufzeitassembly erstellt.

  • Ändern Sie die Laufzeitassembly und erstellen Sie diese neu.

  • Führen Sie das Clientprogramm aus, um sich zu vergewissern, dass die neue Version der Laufzeitassembly verwendet wird, ohne dass das Clientprogramm neu kompiliert wird.

HinweisHinweis

Ihr Computer zeigt möglicherweise für einige der Elemente der Visual Studio-Benutzeroberfläche in der folgenden Anleitung andere Namen oder Standorte an. Diese Elemente sind von der jeweiligen Visual Studio-Version und den verwendeten Einstellungen abhängig. Weitere Informationen finden Sie unter Visual Studio-Einstellungen.

Erstellen einer Schnittstelle

So erstellen Sie das Projekt für die Typäquivalenzschnittstelle

  1. Zeigen Sie in Visual Studio im Menü Datei auf Neu, und klicken Sie dann auf Projekt.

  2. Überprüfen Sie, ob im Dialogfeld Neues Projekt im Bereich Projekttypen der Eintrag Windows ausgewählt ist.Wählen Sie im Bereich Vorlagen den Eintrag Klassenbibliothek aus.Geben Sie im Feld Name die Bezeichnung TypeEquivalenceInterface ein, und klicken Sie auf OK.Das neue Projekt wird erstellt.

  3. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf die Datei "Class1.vb" oder auf die Datei "Class1.cs", und wählen Sie im Kontextmenü die Option Umbenennen aus.Benennen Sie die Datei in ISampleInterface.vb oder ISampleInterface.cs um, und drücken Sie EINGABETASTE.Durch das Umbenennen der Datei wird auch die Klasse in ISampleInterface umbenannt.Diese Klasse stellt die öffentliche Schnittstelle für die Klasse dar.

  4. Klicken Sie mit der rechten Maustaste auf das TypeEquivalenceInterface-Projekt, und wählen Sie im Kontextmenü die Option Eigenschaften aus.Klicken Sie in Visual Basic auf die Registerkarte Kompilieren, oder klicken Sie in Visual C# auf die Registerkarte Erstellen.Legen Sie den Ausgabepfad auf einen gültigen Speicherort auf dem Entwicklungscomputer fest, beispielsweise C:\TypeEquivalenceSample.Dieser Speicherort wird auch später in dieser exemplarischen Vorgehensweise verwendet.

  5. Klicken Sie ohne die Bearbeitung der Projekteigenschaften zu beenden auf die Registerkarte Signierung.Wählen Sie die Option Assembly signieren aus.Klicken Sie in der Liste Schlüsseldatei mit starkem Namen auswählen auf Neu.Geben Sie im Feld Schlüsseldateiname den Namen key.snk ein.Deaktivieren Sie das Kontrollkästchen Schlüsseldatei mit Kennwort schützen.Klicken Sie auf OK.

  6. Öffnen Sie die Datei "ISampleInterface.vb" oder die Datei "ISampleInterface.cs".Fügen Sie der ISampleInterface-Klassendatei den folgenden Code hinzu, um die ISampleInterface-Schnittstelle zu erstellen.

    Imports System.Runtime.InteropServices
    
    <ComImport()>
    <Guid("8DA56996-A151-4136-B474-32784559F6DF")>
    Public Interface ISampleInterface
        Sub GetUserInput()
        ReadOnly Property UserInput As String
    
    
    ...
    
    
    End Interface
    
    using System;
    using System.Runtime.InteropServices;
    
    namespace TypeEquivalenceInterface
    {
        [ComImport]
        [Guid("8DA56996-A151-4136-B474-32784559F6DF")]
        public interface ISampleInterface
        {
            void GetUserInput();
            string UserInput { get; }
    
    
    ...
    
    
        }
    }
    
  7. Klicken Sie im Menü Extras auf GUID erstellen.Klicken Sie im Dialogfeld GUID erstellen auf Registrierungsformat und anschließend auf Kopieren.Klicken Sie auf Beenden.

  8. Löschen Sie die Beispiel-GUID aus dem Guid-Attribut, und fügen Sie die GUID ein, die Sie aus dem Dialogfeld GUID erstellen kopiert haben.Entfernen Sie die geschweiften Klammern ({}) aus der kopierten GUID.

  9. Klicken Sie in Visual Basic im Menü Projekt auf Alle Dateien anzeigen.Überspringen Sie diesen Schritt, wenn Sie Visual C# verwenden.

  10. Erweitern Sie im Projektmappen-Explorer den Ordner Mein Projekt, wenn Sie Visual Basic verwenden.Erweitern Sie den Ordner Eigenschaften, wenn Sie Visual C# verwenden.Doppelklicken Sie auf die Datei "AssemblyInfo.vb" oder auf die Datei "AssemblyInfo.cs".Fügen Sie der Datei das folgende Attribut hinzu:

    <Assembly: ImportedFromTypeLib("")> 
    
    [assembly: ImportedFromTypeLib("")]
    

    Speichern Sie die Datei.

  11. Speichern Sie das Projekt.

  12. Klicken Sie mit der rechten Maustaste auf das TypeEquivalenceInterface-Projekt, und wählen Sie im Kontextmenü die Option Erstellen aus.Die Klassenbibliotheksdatei (.dll) wird kompiliert und im angegebenen Buildausgabepfad (beispielsweise "C:\TypeEquivalenceSample") gespeichert.

Erstellen einer Laufzeitklasse

So erstellen Sie das Projekt für die Typäquivalenzlaufzeit

  1. Zeigen Sie in Visual Studio im Menü Datei auf Neu, und klicken Sie dann auf Projekt.

  2. Überprüfen Sie, ob im Dialogfeld Neues Projekt im Bereich Projekttypen der Eintrag Windows ausgewählt ist.Wählen Sie im Bereich Vorlagen den Eintrag Klassenbibliothek aus.Geben Sie im Feld Name die Bezeichnung TypeEquivalenceRuntime ein, und klicken Sie auf OK.Das neue Projekt wird erstellt.

  3. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf die Datei "Class1.vb" oder auf die Datei "Class1.cs", und wählen Sie im Kontextmenü die Option Umbenennen aus.Benennen Sie die Datei in SampleClass.vb oder in SampleClass.cs um, und drücken Sie EINGABETASTE.Durch das Umbenennen der Datei wird auch die Klasse in SampleClass umbenannt.Diese Klasse implementiert die ISampleInterface-Schnittstelle.

  4. Klicken Sie mit der rechten Maustaste auf das TypeEquivalenceRuntime-Projekt, und wählen Sie im Kontextmenü die Option Eigenschaften aus.Klicken Sie in Visual Basic auf die Registerkarte Kompilieren, oder klicken Sie in Visual C# auf die Registerkarte Erstellen.Legen Sie den Ausgabepfad auf den Speicherort fest, den Sie im TypeEquivalenceInterface-Projekt verwendet haben, beispielsweise C:\TypeEquivalenceSample.

  5. Klicken Sie ohne die Bearbeitung der Projekteigenschaften zu beenden auf die Registerkarte Signierung.Wählen Sie die Option Assembly signieren aus.Klicken Sie in der Liste Schlüsseldatei mit starkem Namen auswählen auf Neu.Geben Sie im Feld Schlüsseldateiname den Namen key.snk ein.Deaktivieren Sie das Kontrollkästchen Schlüsseldatei mit Kennwort schützen.Klicken Sie auf OK.

  6. Klicken Sie mit der rechten Maustaste auf das TypeEquivalenceRuntime-Projekt, und wählen Sie im Kontextmenü die Option Verweis hinzufügen aus.Klicken Sie auf die Registerkarte Durchsuchen, und wechseln Sie zum Ausgabepfadordner.Wählen Sie die Datei "TypeEquivalenceInterface.dll" aus, und klicken Sie auf OK.

  7. Klicken Sie in Visual Basic im Menü Projekt auf Alle Dateien anzeigen.Überspringen Sie diesen Schritt, wenn Sie Visual C# verwenden.

  8. Erweitern Sie im Projektmappen-Explorer den Ordner Verweise.Wählen Sie den TypeEquivalenceInterface-Verweis aus.Legen Sie im Eigenschaftenfenster für den TypeEquivalenceInterface-Verweis die Eigenschaft Bestimmte Version auf False fest.

  9. Fügen Sie der SampleClass-Klassendatei den folgenden Code hinzu, um die SampleClass-Klasse zu erstellen.

    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
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    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();
            }
    
    
    ...
    
    
        }
    }
    
  10. Speichern Sie das Projekt.

  11. Klicken Sie mit der rechten Maustaste auf das TypeEquivalenceRuntime-Projekt, und wählen Sie im Kontextmenü die Option Erstellen aus.Die Klassenbibliotheksdatei (.dll) wird kompiliert und im angegebenen Buildausgabepfad (beispielsweise "C:\TypeEquivalenceSample") gespeichert.

Erstellen eines Clientprojekts

So erstellen Sie das Projekt für den Typäquivalenzclient

  1. Zeigen Sie in Visual Studio im Menü Datei auf Neu, und klicken Sie dann auf Projekt.

  2. Überprüfen Sie, ob im Dialogfeld Neues Projekt im Bereich Projekttypen der Eintrag Windows ausgewählt ist.Wählen Sie im Bereich Vorlagen die Option Konsolenanwendung aus.Geben Sie im Feld Name die Bezeichnung TypeEquivalenceClient ein, und klicken Sie auf OK.Das neue Projekt wird erstellt.

  3. Klicken Sie mit der rechten Maustaste auf das TypeEquivalenceClient-Projekt, und wählen Sie im Kontextmenü die Option Eigenschaften aus.Klicken Sie in Visual Basic auf die Registerkarte Kompilieren, oder klicken Sie in Visual C# auf die Registerkarte Erstellen.Legen Sie den Ausgabepfad auf den Speicherort fest, den Sie im TypeEquivalenceInterface-Projekt verwendet haben, beispielsweise C:\TypeEquivalenceSample.

  4. Klicken Sie mit der rechten Maustaste auf das TypeEquivalenceClient-Projekt, und wählen Sie im Kontextmenü die Option Verweis hinzufügen aus.Klicken Sie auf die Registerkarte Durchsuchen, und wechseln Sie zum Ausgabepfadordner.Wählen Sie die Datei "TypeEquivalenceInterface.dll" (und nicht die Datei "TypeEquivalenceRuntime.dll") aus, und klicken Sie auf OK.

  5. Klicken Sie in Visual Basic im Menü Projekt auf Alle Dateien anzeigen.Überspringen Sie diesen Schritt, wenn Sie Visual C# verwenden.

  6. Erweitern Sie im Projektmappen-Explorer den Ordner Verweise.Wählen Sie den TypeEquivalenceInterface-Verweis aus.Legen Sie im Eigenschaftenfenster für den TypeEquivalenceInterface-Verweis die Eigenschaft Interop-Typen einbetten auf True fest.

  7. Fügen Sie der Datei "Module1.vb" oder der Datei "Program.cs" den folgenden Code hinzu, um das Clientprogramm zu erstellen:

    Imports TypeEquivalenceInterface
    Imports System.Reflection
    
    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
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using TypeEquivalenceInterface;
    using System.Reflection;
    
    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();
            }
        }
    }
    
  8. Drücken Sie STRG+F5, um das Programm zu erstellen und auszuführen.

Ändern der Schnittstelle

So ändern Sie die Schnittstelle

  1. Zeigen Sie in Visual Studio im Menü Datei auf Öffnen, und klicken Sie dann auf Projekt/Projektmappe.

  2. Klicken Sie im Dialogfeld Projekt öffnen mit der rechten Maustaste auf das TypeEquivalenceInterface-Projekt, und klicken Sie dann auf Eigenschaften.Klicken Sie auf die Registerkarte Anwendung.Klicken Sie auf die Schaltfläche Assemblyinformationen.Ändern Sie den Wert für die Assemblyversion und den Wert für die Dateiversion in 2.0.0.0.

  3. Öffnen Sie die Datei "ISampleInterface.vb" oder die Datei "ISampleInterface.cs".Fügen Sie der ISampleInterface-Schnittstelle die folgende Codezeile hinzu:

    Function GetDate() As Date
    
    DateTime GetDate();
    

    Speichern Sie die Datei.

  4. Speichern Sie das Projekt.

  5. Klicken Sie mit der rechten Maustaste auf das TypeEquivalenceInterface-Projekt, und wählen Sie im Kontextmenü die Option Erstellen aus.Eine neue Version der Klassenbibliotheksdatei (.dll) wird kompiliert und im angegebenen Buildausgabepfad (beispielsweise "C:\TypeEquivalenceSample") gespeichert.

Ändern der Laufzeitklasse

So ändern Sie die Laufzeitklasse

  1. Zeigen Sie in Visual Studio im Menü Datei auf Öffnen, und klicken Sie dann auf Projekt/Projektmappe.

  2. Klicken Sie im Dialogfeld Projekt öffnen mit der rechten Maustaste auf das TypeEquivalenceRuntime-Projekt, und klicken Sie dann auf Eigenschaften.Klicken Sie auf die Registerkarte Anwendung.Klicken Sie auf die Schaltfläche Assemblyinformationen.Ändern Sie den Wert für die Assemblyversion und den Wert für die Dateiversion in 2.0.0.0.

  3. Öffnen Sie die Datei "SampleClass.vb" oder die Datei "SampleClass.cs".Fügen Sie der SampleClass-Klasse die folgenden Codezeilen hinzu:

    Public Function GetDate() As DateTime Implements ISampleInterface.GetDate
        Return Now
    End Function
    
    public DateTime GetDate()
    {
        return DateTime.Now;
    }
    

    Speichern Sie die Datei.

  4. Speichern Sie das Projekt.

  5. Klicken Sie mit der rechten Maustaste auf das TypeEquivalenceRuntime-Projekt, und wählen Sie im Kontextmenü die Option Erstellen aus.Eine aktualisierte Version der Klassenbibliotheksdatei (.dll) wird kompiliert und im zuvor angegebenen Buildausgabepfad (beispielsweise "C:\TypeEquivalenceSample") gespeichert.

  6. Im Datei-Explorer öffnen Sie den Ausgabepfadordner (beispielsweise, C:\TypeEquivalenceSample).Doppelklicken Sie auf die Datei "TypeEquivalenceClient.exe", um das Programm auszuführen.Das Programm entspricht der neuen Version der TypeEquivalenceRuntime-Assembly ohne neu kompiliert worden zu sein.

Siehe auch

Referenz

/link (Visual Basic)

/link (C#-Compileroptionen)

Konzepte

C#-Programmierhandbuch

Weitere Ressourcen

Visual Basic-Programmierhandbuch

Programmieren mit Assemblys