Implementierungsprobleme für ADSI-Anbieter

Implementieren Sie zunächst die COM-Schnittstelle IDirectoryObject,um ADSI-Schnittstellen zu implementieren. Indem Sie diese Schnittstelle als minimale Mehraufwandsebene bereitstellen, stellen Sie Clientanwendungen das Steuerelement bereit, das für den direkten Zugriff auf Verzeichnisobjekte aus dem Verzeichnis erforderlich ist, und nicht über den ADSI-Cache, der die Netzwerkleistung optimiert. Die Verwendung dieser Schnittstelle bietet auch Ihre eigene Implementierung mit der größten Flexibilität.

Implementieren Sie zweitens die grundlegenden ADSI-Schnittstellen, IADs, IADsContainer, IADsCollectionund die IADsPropertyValue-, IADsPropertyEntry-und IADsPropertyList-Eigenschaftencacheschnittstellen. IADsGroup und IADsMembers sind ebenfalls Schnittstellen, die häufig von Systemverwaltungssoftware gefordert werden.

Implementieren Sie drittens die Schemaverwaltungsschnittstellen, wenn Ihr Verzeichnisdienst über ein zugrunde liegendes Schema verfügt: IADsClass, IADsProperty, IADsSyntax. Wenn kein zugrunde liegendes Schema vorhanden ist, verwenden Sie diese Schnittstellen, um die vom Verzeichnisdienst verwendeten Klassen und Eigenschaften zu abstrahieren. Schemas können verwendet werden, um die Features Ihres Verzeichnisdiensts auf ADSI-Clients zu veröffentlichen.

Sammlungen

ADSI-Anbieterkomponenten können einem von drei Modellen zum Zwischenspeichern von Sammlungen während der Enumeration folgen. Die Wahl eines Cachemodells bestimmt das Verhalten von ADSI, wenn ein Objekt in einer Sammlung aus dem zugrunde liegenden Verzeichnisdienst außerhalb von ADSI gelöscht wird.

Die Cachemodelle umfassen Folgendes:

  • Sammlungen, die im Voraus zwischengespeichert werden. Die Auflistung von Objektinstanzen wird vollständig aus dem zugrunde liegenden Verzeichnisdienst abgerufen, wenn IADsCollection::get _ _ NewEnum aufgerufen wird, um ein neues Enumeratorobjekt zu erstellen. Wenn das Quellobjekt für eine Active Directory-Objektinstanz in der abgerufenen Sammlung aus dem zugrunde liegenden Verzeichnisdienst gelöscht wird, erkennt der Client den Löschvorgang erst, wenn eine IADs::GetInfo oder IADs::SetInfo versucht, auf die Sammlung zu zugreifen.
  • Inkrementell zwischengespeicherte Auflistungen. Die Auflistung wird vom zugrunde liegenden Verzeichnisdienst nach und nach abgerufen, wenn IEnumVARIANT::Next aufgerufen wird. IEnumVARIANT::Reset wird an den Anfang der Sammlung im Cache zurückgesetzt, und IEnumVARIANT::Next gibt zwischengespeicherte Objekte zurück, bis das Ende des Caches erreicht ist. An diesem Punkt werden neue Objekte aus dem zugrunde liegenden Speicher hinzugefügt. Wenn sich eine Active Directory-Objektinstanz im Cache befindet, wird der Client erst dann über die Löschung aus dem zugrunde liegenden Verzeichnisdienst informiert, wenn eine IADs::GetInfo oder IADs::SetInfo versucht, auf das Objekt zu zugreifen.
  • Auflistungen werden nicht zwischengespeichert. Die Auflistung wird vom zugrunde liegenden Verzeichnisdienst nach und nach abgerufen, wenn IEnumVARIANT::Next aufgerufen wird. IEnumVARIANT::Reset wird an den Anfang der Auflistung im zugrunde liegenden Speicher zurückgesetzt. IEnumVARIANT::Next- und IEnumVARIANT::Reset-Vorgänge können keine gelöschten Objekte abrufen, da die Objekte bei Bedarf vom zugrunde liegenden Verzeichnisdienst abgerufen werden. Nur das aktuelle Objekt wird zwischengespeichert. Wenn das aktuelle Objekt gelöscht wird, wird der Client erst dann vom Löschvorgang aus dem zugrunde liegenden Verzeichnisdienst informiert, wenn ein IADs::GetInfo- oder IADs::SetInfo-Versuch versucht, auf das Objekt zu zugreifen.

Beachten Sie unabhängig vom Cachemodell, dass die ADSI-Enumeration Active Directory-Dienstschnittstellen an den Aufrufer zurückgibt. Um den Aufwand für das Abrufen eines neuen Schnittstellenzeigers zu vermeiden, sollten ADSI-Anwendungen die zurückgegebenen Schnittstellenzeiger für Objekte zwischenspeichern, die sie bearbeiten möchten. Beispielsweise kann eine Visual Basic Anwendung, die einen Container auflistet und ein Listenfeld mit Namen auffüllt, die Schnittstellenze0er zwischenspeichern, die den Namen zur späteren Verwendung zugeordnet sind. Dieser Ansatz bietet eine höhere Leistung als das Auflisten des Listenfelds während der Enumeration und das Abrufen eines neuen Schnittstellenzeigers, wenn der Benutzer eine Auswahl trifft.

Informationen zu Dispatch-IDs

IDispatch ist eine von COM definierte Automatisierungsschnittstelle für Controller, die com-Schnittstellen nicht direkt verwenden. Der Zugriff auf ein Objekt über IDispatch wird als namensgebundener oder spät gebundener Zugriff bezeichnet, da er zur Laufzeit ("spät") auftritt und Zeichenfolgennamen von Eigenschaften und Methoden verwendet, um Verweise ("Name") aufzulösen. Zur Laufzeit übergeben Clients den Zeichenfolgennamen der Eigenschaft oder Methode, die bzw. die sie aufrufen möchten, an die IDispatch::GetIDsOfNames()-Methode. Wenn die Eigenschaft oder Methode für das Objekt vorhanden ist, wird der Dispatchbezeichner (dispID) der entsprechenden Funktion abgerufen. Die dispID wird dann verwendet, um die Funktion über IDispatch::Invoke ()auszuführen. Mithilfe von IDispatch werden Eigenschaften und Methoden auf den Schnittstellen, die von einem einzelnen -Objekt verfügbar gemacht werden, als flache Liste angezeigt. Da der namensgebundene Zugriff zwei Funktionsaufrufe erfordert, ist er weniger effizient als die direkte Verwendung einer COM-Schnittstelle. Clients wird empfohlen, die ADSI COM-Schnittstellen für die Objekte zu verwenden, wenn die Leistung berücksichtigt wird. Erweiterte Automatisierungscontroller wie Visual Basic 4.0 können andere COM-Schnittstellen sowie IDispatch aufrufen, wenn die Schnittstellen den Automation-Einschränkungen für Datentypen und parameterübergibt.

ADSI-Anbieter generieren dispIDs dynamisch für jedes Active Directory-Objekt. Die dispIDs, die über IDispatch::GetIDsOfNames für ein bestimmtes Objekt abgerufen werden, sind die generierten Werte, aber nicht die Werte, die in der IDL für das Objekt enthalten sind. IDispatch-Benutzer müssen GetIDsOfNames aufrufen, um zur Laufzeit gültige DispIDs zu erhalten.

Typinformationen und Typbibliotheken

Das ADSI SDK stellt die Typbibliothek Activeds.tlb bereit, die alle von ADSI unterstützten Standardschnittstellen dokumentiert. Ein Anbieter muss eine ähnliche Typbibliothek für alle Schnittstellen in Activeds.tlb sowie alle zusätzlichen Typdaten für die Schnittstellen, die in der Anbieterkomponente implementiert sind, zur Verfügung stellen.

Im Folgenden finden Sie ein IDL-Codebeispiel.

[ object, uuid(IID_IADsXYZ), oleautomation, dual ]
interface IADsXYZ: IDispatch
{
// Read-only properties.
[propget]
HRESULT AReadOnlyProp ([out, retval]BSTR *pbstrAReadOnlyProp);
 
// Read/write properties.
[propget]
HRESULT AReadWriteProp ([out, retval]long *plAReadWriteProp);
[propput]
HRESULT AReadWriteProp ([in]long lAReadWriteProp);
 
// Methods.
HRESULT AMethod ([in]DATE dateInParameter,
[out, retval]BSTR *pbstrReturnValue);
};

Threadsicherheit

Die Component Object Model (COM) beschreibt die folgenden drei Threadingmodelle. COM-Anwendungen geben an, welches Modell verwendet wird, wenn die COM-Bibliothek mithilfe der Funktionen CoInitialize und CoInitializeEx initialisiert wird:

  • Singlethreading. Das Singlethreadmodell geht von einem einzelnen Ausführungsthread in einem Prozess aus und setzt weiter voraus, dass COM-Datenstrukturen in einem Prozess keine Zugriffsserialisierung benötigen.
  • Apartmentthreading. Ein COM-Objekt ist dem Thread zugeordnet, der es erstellt hat. Aufrufe eines Objekts in einem anderen Thread müssen von dem Thread ausgeführt werden, der dieses Objekt erstellt hat. Hierzu ruft der Quellthread einen Clientproxy auf, der den Methodenaufruf anordnt und ihn über die Win32-Nachrichtenwarteschlange, die dem Zielthread zugeordnet ist, an eine Serverstubfunktion im Zielthread übermittelt.
  • Kostenloses Threading. COM-Objekte werden als threadsicher angenommen. Mehrere Threads sind ohne serialisierte Serialisierung auf ein beliebiges Objekt im Prozess zugreifen können.

ADSI geht nicht von einem bestimmten Threadingmodell aus. Writer von Anbieterkomponenten sollten das FreeThreading-Modell annehmen und die Konsistenz ihrer internen Datenstrukturen gewährleisten, indem sie sie vor threadunsicheren, d. b. unkoordinierten Aktualisierungen durch die Verwendung von Synchronisierungsobjekten wie kritischen Abschnitten oder Semaphoren schützen.

Objektsperrung

ADSI erzwingt oder definiert kein Objektsperrschema. Anbieter für Namespaces, die die Zugriffsserialisierung mithilfe von Sperren unterstützen, können das zugrunde liegende Sperrschema über anbieterspezifische Erweiterungen für ADSI verfügbar machen.

Eigenschaftennamen innerhalb eines Schemas

ADSI stellt Eigenschaften als Eigenschaftenobjekte innerhalb des ADSI-Schemacontainers dar. Dies erfordert, dass Eigenschaftsnamen innerhalb jedes Schemacontainers eindeutig sind. Der Anbieter muss sicherstellen, dass es keine Namenskollisionen gibt.

Primäre Schnittstelle

Wenn ein Anbieter nicht identifizieren kann, welche Schnittstelle als primäre Schnittstelle zurückgegeben werden soll, sollten _ IID-IADs zurückgegeben werden. Dies ermöglicht den namensgebundenen Zugriff auf alle Eigenschaften eines Objekts über IDispatch und die Methoden IADs::Get, IADs::GetEx, IADs::P utund IADs::P utEx.