Implementierungsprobleme für ADSI-Anbieter

Um ADSI-Schnittstellen zu implementieren, implementieren Sie zuerst die COM-Schnittstelle IDirectoryObject. Indem Sie diese Schnittstelle als minimale Overheadebene bereitstellen, stellen Sie Clientanwendungen die Steuerung bereit, die für den Zugriff auf Verzeichnisobjekte direkt aus dem Verzeichnis statt über den ADSI-Cache erforderlich ist, wodurch die Netzwerkleistung optimiert wird. Die Verwendung dieser Schnittstelle ermöglicht auch Ihre eigene Implementierung mit größtmöglicher Flexibilität.

Implementieren Sie anschließend die grundlegenden ADSI-Schnittstellen, IADs, IADsContainer, IADsCollection und die Cacheschnittstellen der Eigenschaften IADsPropertyValue, IADsPropertyEntry, IADsPropertyList . IADsGroup und IADsMembers sind auch Schnittstellen, die von Systemverwaltungssoftware häufig nachgefragt werden.

Drittens implementieren Sie 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 Zwischenspeicherungsmodells bestimmt das Verhalten von ADSI, wenn ein Objekt in einer Auflistung aus dem zugrunde liegenden Verzeichnisdienst außerhalb von ADSI gelöscht wird.

Zu den Zwischenspeicherungsmodellen gehören:

  • Sammlungen werden vorab zwischengespeichert. 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 ein Active Directory-Objekt instance in der abgerufenen Auflistung aus dem zugrunde liegenden Verzeichnisdienst gelöscht wird, erkennt der Client den Löschvorgang erst, wenn ein IADs::GetInfo oder IADs::SetInfo versucht, auf die Auflistung zuzugreifen.
  • Sammlungen werden inkrementell zwischengespeichert. Die Auflistung wird aus dem zugrunde liegenden Verzeichnisdienst jeweils ein Objekt abgerufen, wenn IEnumVARIANT::Next aufgerufen wird. IEnumVARIANT::Reset kehrt zum Anfang der Auflistung im Cache zurück, 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 ein Active Directory-Objekt instance im Cache befindet, wird der Client erst dann vom Löschen aus dem zugrunde liegenden Verzeichnisdienst informiert, wenn ein IADs::GetInfo oder IADs::SetInfo versucht, auf das Objekt zuzugreifen.
  • Sammlungen werden nicht zwischengespeichert. Die Auflistung wird aus dem zugrunde liegenden Verzeichnisdienst jeweils ein Objekt abgerufen, wenn IEnumVARIANT::Next aufgerufen wird. IEnumVARIANT::Reset kehrt zum Anfang der Auflistung im zugrunde liegenden Speicher zurück. IEnumVARIANT::Next - und IEnumVARIANT::Reset-Vorgänge können nicht gelöschte Objekte abrufen, da die Objekte bei Bedarf aus dem 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öschen aus dem zugrunde liegenden Verzeichnisdienst informiert, wenn ein IADs::GetInfo oder IADs::SetInfo versucht, auf das Objekt zuzugreifen.

Beachten Sie unabhängig vom Zwischenspeicherungsmodell, dass die ADSI-Enumeration Active Directory-Dienstschnittstellen an den Aufrufer zurückgibt. Um den Mehraufwand beim 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 aufzählt und ein Listenfeld mit Namen auffüllt, die Schnittstellenzeiger zwischenspeichern, die den Namen zur späteren Verwendung zugeordnet sind. Dieser Ansatz bietet eine höhere Leistung als das Auffüllen des Listenfelds während der Enumeration und das Abrufen eines neuen Schnittstellenzeigers, wenn der Benutzer eine Auswahl trifft.

Informationen zu Versand-IDs

IDispatch ist eine Automatisierungsschnittstelle, die von COM für Controller definiert wird, die keine COM-Schnittstellen direkt verwenden. Der Zugriff auf ein Objekt über IDispatch wird als namensgebundener oder spät gebundener Zugriff bezeichnet, da er zur Laufzeit ("spät") erfolgt und Zeichenfolgennamen von Eigenschaften und Methoden verwendet, um Verweise ("Name") aufzulösen. Zur Laufzeit übergeben Clients den Zeichenfolgennamen der Eigenschaft oder Methode, die sie aufrufen möchten, an die IDispatch::GetIDsOfNames()-Methode. Wenn die Eigenschaft oder Methode für das Objekt vorhanden ist, wird der Verteilerbezeichner (dispID) der entsprechenden Funktion abgerufen. Die dispID wird dann verwendet, um die Funktion über IDispatch::Invoke() auszuführen. Mit IDispatch werden Eigenschaften und Methoden für die Schnittstellen, die von einem einzelnen Objekt verfügbar gemacht werden, als flache Liste angezeigt. Da für den namengebundenen Zugriff zwei Funktionsaufrufe erforderlich sind, ist dies weniger effizient als die direkte Verwendung einer COM-Schnittstelle. Clients werden empfohlen, die ADSI-COM-Schnittstellen für die Objekte zu verwenden, wenn die Leistung eine Rolle spielt. Advanced Automation-Controller wie Visual Basic 4.0 können andere COM-Schnittstellen sowie IDispatch aufrufen, wenn die Schnittstellen die Automation-Einschränkungen für Datentypen und Parameterübergaben erfüllen.

ADSI-Anbieter generieren dynamisch dispIDs für jedes Active Directory-Objekt. Die über IDispatch::GetIDsOfNames für ein bestimmtes Objekt abgerufenen dispIDs 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 gültige dispIDs zur Laufzeit abzurufen.

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 bereitstellen, die in der Anbieterkomponente implementiert sind.

Es folgt 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

Das 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:

  • Einzelthreading. Das Einzelthreadmodell setzt einen einzelnen Ausführungsthread in einem Prozess voraus, und setzt außerdem voraus, dass COM-Datenstrukturen in einem Prozess keine Zugriffsserialisierung benötigen.
  • Apartmentthreading. Dem Thread, von dem es erstellt wurde, ist ein COM-Objekt zugeordnet. 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 anordnet und über die win32-Nachrichtenwarteschlange, die dem Zielthread zugeordnet ist, an eine Serverstubfunktion im Zielthread übermittelt.
  • Freies Threading. COM-Objekte werden als threadsicher angenommen. Mehrere Threads können auf jedes Objekt im Prozess zugreifen, ohne dass eine Serialisierung erzwungen wird.

ADSI setzt kein bestimmtes Threadingmodell voraus. Autoren von Anbieterkomponenten sollten das freie Threadingmodell übernehmen und die Konsistenz ihrer internen Datenstrukturen gewährleisten, indem sie sie vor threadunsicheren, d. h. unkoordinierten Updates durch die Verwendung von Synchronisierungsobjekten wie kritischen Abschnitten oder Semaphoren schützen.

Objektsperre

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 Eigenschaftsobjekte innerhalb des ADSI-Schemacontainers dar. Dies erfordert, dass Eigenschaftennamen innerhalb jedes Schemacontainers eindeutig sind. Der Anbieter muss sicherstellen, dass es keine Namenskonflikte gibt.

Primäre Schnittstelle

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