Freigeben über


Vererbung, Aggregation und Einkapselung

COM-Wiederverwendbarkeit in .NET Framework wird durch Vererbung erreicht. COM-Typen können bei der Vererbung als Basisklasse auftreten. Verwenden Sie Modelle der Vererbung, Aggregation oder Einkapselung unter folgenden Umständen:

Modell Verwendungszweck
Vererbung Offenlegen des verwalteten Objekts als äußeres Objekt.
Aggregation Aktivieren des äußeren Objekts, um die Implementierung der Schnittstelle eines anderen Objekts ohne Veränderung offen zu legen.
Einkapselung Aktivieren des äußeren Objekts, um das Verhalten des inneren Objekts zu ändern.

Vererbung

Wenn verwaltete Schnittstellen in COM verwendet werden, erweitern sie immer IUnknown oder IDispatch, selbst wenn sie von Schnittstellen der verwalteten Seite geerbt wurden. Dieselbe Regel gilt für die Klassenschnittstellen, die für verwaltete Klassen generiert werden.

Das COM-Modell wird von .NET Framework durch Hinzufügen von Implementierungsvererbung erweitert und dadurch wiederverwendbar. Verwaltete Typen können sowohl direkt als auch indirekt von einer Co-Klasse abgeleitet werden, genauer gesagt, vom RCW (Runtime Callable Wrapper), der durch die Common Language Runtime generiert wird. Der abgeleitete Typ kann alle Methoden und Eigenschaften des COM-Objekts, ebenso wie die in verwaltetem Code implementierten, offen legen. Das resultierende Objekt wird teils in verwaltetem, teils in nicht verwaltetem Code implementiert.

Um als Basisklasse qualifiziert zu sein, muss die Co-Klasse folgende Voraussetzungen erfüllen:

Verwaltete Typen können den RCW für eine qualifizierende Co-Klasse erweitern und die durch das Basisobjekt bereitgestellten Methoden außer Kraft setzen. Wenn Sie irgendeine Methode außer Kraft setzen wollen, müssen Sie dies für alle Basismethoden einer Schnittstelle tun.

Ein verwalteter Typ erbt von einem RCW auf dieselbe Weise wie von einem verwalteten Basisobjekt. Im folgenden Codebeispiel wird die verwaltete Catapult-Klasse von dem COM-Typ AcmeLib.Slingshot abgeleitet.

#using "AcmeLib.dll"    // Provides definition of Slingshot.

__gc class Catapult : public AcmeLib.Slingshot  // Extends the COM type.
{
    // Delegates to base implementation.
    Load() { //... };  
   
    Fire()               
    {
        // Engages in some behavior before delegating to the base 
        // implementation.
        Slingshot::Fire();
    }

    // The Aim method needs to be overridden.
    Aim() { //... }         
}
Catapult *cp = new Catapult();

// Calls derived implementation.
cp->Load();
// Calls base implementation.
cp->Aim();
// Calls derived which delegates to base.
cp->Fire();

Aggregation

Um die Schnittstellen einer COM-Klasse so offen zu legen, als wären sie auf einer zweiten COM-Klasse implementiert worden, wird die erste Klasse von der zweiten zusammengesetzt. Ein .NET-Objekt kann durch ein COM-Objekt zusammengesetzt werden. In diesem Fall sind alle Schnittstellen des Objekts, auch seine Klassenschnittstelle, durch das äußere Objekt verfügbar. Aufrufe werden vom inneren .NET-Objekt über dessen IUnknown-Methoden zum steuernden IUnknown delegiert.

Aggregation ist ein wenig komplexer als die im nächsten Abschnitt beschriebene Einkapselung. In der Regel wird sie zur Aktivierung des äußeren Objekts verwendet, um die Schnittstellenimplementierung eines anderen Objekts ohne Änderung offen zu legen. Alle verwalteten Objekte unterstützen automatisch die Aggregation im Sinne von COM. Dabei wird das verwaltete Objekt als das innere Objekt verwendet. Um ein verwaltetes Objekt zusammenzusetzen, erstellt das nicht verwaltete äußere Objekt durch Aufruf von CoCreateInstance das verwaltete innere Objekt. Danach wird IUnknown des äußeren Objekts als OuterUnknown-Parameter übergeben. Wenn ein äußeres IUnknown während der Konstruktion einem verwalteten Objekt übergeben wird, wird die Schnittstelle durch das verwaltete Objekt zwischengespeichert und wie folgt verwendet:

  • Das äußere Objekt behält das nicht delegierende IUnknown des inneren IUnknown bei. Das nicht delegierende IUnknown verhält sich wie ein normales IUnknown, d. h., es wird erfolgreich aufgerufen, wenn das Objekt die Schnittstelle implementiert, andernfalls schlägt der Aufruf fehl. Das nicht delegierende IUnknown leitet den Aufruf nicht an das äußere Objekt weiter.
  • Wird eine nicht vom inneren Objekt unterstützte Schnittstelle abgefragt, delegiert das innere Objekt den Aufruf zur Schnittstelle IUnknown des äußeren Objekts.
  • Alle Aufrufe der QueryInterface-Methode, der AddRef-Methode und der Release-Methode des inneren Objekts werden an IUnknown des äußeren Objekts delegiert.

Durch diese drei Verhaltensweisen kann jedes beliebige verwaltete Objekt zusammengesetzt werden. Durch diese Art von Aggregationsbeziehung kann ein einzelnes COM-Objekt teils in verwaltetem (innerer Bereich) und teils in nicht verwaltetem Code (äußerer Bereich) implementiert sein.

Einkapselung

Ein .NET-Objekt kann ein COM-Objekt enthalten, indem es seine Metadaten in eine .NET-Assembly importiert und dann ein Datenmember dieses Typs innerhalb einer anderen Klasse deklariert. Wie bei der normalen COM-Einkapselung können Sie die Schnittstellen des COM-Objekts in Ihren eigenen Schnittstellenimplementierungen aufrufen. Das eingekapselte Objekt wird aber nicht außerhalb der Klasse offen gelegt. Einkapselung ist einfacher als Aggregation. In der Regel wird Einkapselung dann eingesetzt, wenn das äußere Objekt das Verhalten des inneren Objekts beeinflussen soll. Dazu erstellt das äußere Objekt einfach eine Instanz des inneren in seinem Konstruktor und delegiert gegebenenfalls Aufrufe zum inneren Objekt. Das äußere Objekt entscheidet, welche Aufrufe delegiert und welche direkt verarbeitet werden. Die Laufzeit stellt keine besonderen Anforderungen an Objekte zur Unterstützung der Einkapselung.

Ein COM-Objekt kann auch ein .NET-Objekt enthalten. Das COM-Objekt verhält sich gegenüber Clients so, als wäre das enthaltene ein beliebiges COM-Objekt.

Siehe auch

Erweitertes COM-Interop | COM-Komponenten für .NET Framework verfügbar machen | Offenlegen von .NET Framework-Komponenten in COM