Implementierungsprobleme für ADSI-Anbieter

Um ADSI-Schnittstellen zu implementieren, implementieren Sie zuerst die COM-Schnittstelle IDirectoryObject. Durch die Bereitstellung dieser Schnittstelle als minimaler Aufwandsebene geben Sie Clientanwendungen an, die zum Direkten Zugriff auf Verzeichnisobjekte aus dem Verzeichnis erforderlich sind, anstatt über den ADSI-Cache, der die Netzwerkleistung optimiert. Die Verwendung dieser Schnittstelle liefert auch Ihre eigene Implementierung mit der meisten Flexibilität.

Implementieren Sie zweitens die grundlegenden ADSI-Schnittstellen, IADsContainer, IADsCollection, IADsCollection und die IADsPropertyValue, IADsPropertyEntry, IADsPropertyList-Eigenschaftscacheschnittstellen. IADsGroup und IADsMembers sind auch Schnittstellen in häufiger Nachfrage nach Systemadministrationssoftware.

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 Klassen und Eigenschaften abstrahieren zu können, die vom Verzeichnisdienst verwendet werden. Schemas können verwendet werden, um die Features Ihres Verzeichnisdiensts in ADSI-Clients zu veröffentlichen.

Sammlungen

ADSI-Anbieterkomponenten können eine von drei Modellen für Zwischenspeicherungssammlungen während der Enumeration folgen. Die Auswahl eines Zwischenspeichermodells bestimmt das Verhalten von ADSI, wenn ein Objekt in einer Auflistung aus dem zugrunde liegenden Verzeichnisdienst außerhalb von ADSI gelöscht wird.

Die Zwischenspeicherungsmodelle umfassen:

  • Sammlungen, die im Voraus zwischengespeichert wurden. Die Auflistung von Objektinstanzen wird aus dem zugrunde liegenden Verzeichnisdienst in seiner Gesamten abgerufen, wenn IADsCollection::get__NewEnum aufgerufen wird, um ein neues Aufzählungsobjekt zu erstellen. Wenn das Quellobjekt für eine Active Directory-Objektinstanz in der abgerufenen Auflistung aus dem zugrunde liegenden Verzeichnisdienst gelöscht wird, erkennt der Client das Löschen erst, wenn eine IADs::GetInfo oder IADs::SetInfo versucht, auf die Auflistung zuzugreifen.
  • Auflistungen inkrementell zwischengespeichert. Die Auflistung wird aus dem zugrunde liegenden Verzeichnisdienst ein Objekt gleichzeitig abgerufen, wenn IEnumVARIANT::Next aufgerufen wird. IEnumVARIANT::Reset wird am Anfang der Auflistung im Cache zurückgegeben und IEnumVARIANT ::Next gibt zwischengespeicherte Objekte zurück, bis das Ende des Caches erreicht ist, an welchem Punkt neue Objekte aus dem zugrunde liegenden Speicher hinzugefügt werden. Wenn sich eine Active Directory-Objektinstanz im Cache befindet, wird der Client nicht über seine Löschung aus dem zugrunde liegenden Verzeichnisdienst informiert, bis eine IADs::GetInfo oder IADs::SetInfo versucht, auf das Objekt zuzugreifen.
  • Auflistungen werden nicht zwischengespeichert. Die Auflistung wird aus dem zugrunde liegenden Verzeichnisdienst ein Objekt gleichzeitig abgerufen, wenn IEnumVARIANT::Next aufgerufen wird. IEnumVARIANT::Reset wird am Anfang der Auflistung im zugrunde liegenden Speicher zurückgegeben. IEnumVARIANT::Next and IEnumVARIANT::Reset-Vorgänge können gelöschte Objekte nicht abrufen, da die Objekte auf Bedarf aus dem zugrunde liegenden Verzeichnisdienst abgerufen werden. Nur das aktuelle Objekt wird zwischengespeichert; wenn das aktuelle Objekt gelöscht wird, wird der Client nicht über seine Löschung aus dem zugrunde liegenden Verzeichnisdienst informiert, bis eine IADs::GetInfo oder IADs::SetInfo versucht, auf das Objekt zuzugreifen.

Unabhängig vom Zwischenspeicherungsmodell beachten Sie, dass ADSI-Aufzählung Active Directory-Dienstschnittstellen an den Aufrufer zurückgibt. Um den Aufwand zum 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, zwischenspeichern, die den Namen zugeordnet sind. Dieser Ansatz bietet größere Leistung als das Auffüllen des Listenfelds während der Aufzählung und abrufen eines neuen Schnittstellenzeigers, wenn der Benutzer eine Auswahl macht.

Informationen zum Senden von IDs

IDispatch ist eine Automatisierungsschnittstelle, die von COM für Controller definiert ist, die keine COM-Schnittstellen direkt verwenden. Der Zugriff auf ein Objekt über IDispatch wird als Name gebundener oder spät gebundener Zugriff bezeichnet, da er zur Laufzeit ("spät") auftritt und Zeichenfolgennamen von Eigenschaften und Methoden verwendet, um Verweise ("Name") zu lösen. Zur Laufzeit übergeben Clients den Zeichenfolgennamen der Eigenschaft oder Methode, die sie in die IDispatch::GetIDsOfNames()-Methode aufrufen möchten. Wenn die Eigenschaft oder Methode im Objekt vorhanden ist, wird der Versandbezeichner (dispID) der entsprechenden Funktion abgerufen. Die dispID wird dann verwendet, um die Funktion über IDispatch::Invoke() auszuführen. Die Verwendung von IDispatch, Eigenschaften und Methoden auf den Schnittstellen, die durch ein einzelnes Objekt verfügbar gemacht werden, werden als flache Liste angezeigt. Da der namegebundene Zugriff zwei Funktionsaufrufe erfordert, ist sie weniger effizient als die direkte Verwendung einer COM-Schnittstelle. Clients werden empfohlen, die ADSI-COM-Schnittstellen auf den Objekten zu verwenden, wenn die Leistung eine Erwägung ist. Erweiterte Automatisierungscontroller wie Visual Basic 4.0 können andere COM-Schnittstellen sowie IDispatch aufrufen, wenn die Schnittstellen den Automatisierungseinschränkungen für Datentypen und Parameterübergabe entsprechen.

ADSI-Anbieter generieren dispIDs dynamisch 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 sich im IDL für das Objekt befinden. IDispatch-Benutzer müssen GetIDsOfNames aufrufen, um gültige dispIDs zur Laufzeit abzurufen.

Typinformationen und Typbibliotheken

Das ADSI SDK stellt eine Typbibliothek, Activeds.tlb, bereit, die alle Standardschnittstellen dokumentiert, die von ADSI unterstützt werden. Ein Anbieter muss eine ähnliche Typbibliothek für alle Schnittstellen bereitstellen, die in Activeds.tlb gefunden wurden, sowie alle zusätzlichen Typdaten für die in der Anbieterkomponente implementierten Schnittstellen.

Das folgende Beispiel ist 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-Objektmodell (COM) beschreibt die folgenden drei Threadingmodelle. COM-Anwendungen geben an, welches Modell beim Initialisieren der COM-Bibliothek mithilfe der Funktionen "CoInitialize" und "CoInitializeEx" verwendet wird:

  • Einzelne Threading. Das einzelne Threaded-Modell geht davon aus, dass in einem Prozess ein einzelner Thread ausgeführt wird, weiter davon ausgegangen wird, dass COM-Datenstrukturen in einem Prozess keine Serialisierung benötigen.
  • Apartmentthreading. Ein COM-Objekt ist dem Thread zugeordnet, der es erstellt hat. Aufrufe eines Objekts auf einem anderen Thread müssen vom Thread ausgeführt werden, der dieses Objekt erstellt hat. Dazu ruft der Quellthread einen Clientproxy auf, der den Methodenaufruf anordnt und an eine Server-Stubfunktion im Zielthread über die Win32-Nachrichtenwarteschlange angibt, die dem Zielthread zugeordnet ist.
  • Freithreading. COM-Objekte werden als Thread sicher angenommen. Mehrere Threads können auf jedes Objekt im Prozess ohne Serialisierung zugreifen.

ADSI nimmt kein bestimmtes Threadingmodell an. Autoren von Anbieterkomponenten sollten das kostenlose Threadingmodell übernehmen und die Konsistenz ihrer internen Datenstrukturen gewährleisten, indem sie vor threadunsicheren, d. h. nicht koordinierten, Updates über die Verwendung von Synchronisierungsobjekten wie kritischen Abschnitten oder Semaphoren geschützt werden.

Objektsperre

ADSI legt kein Objektsperrschema fest oder definiert diese. Anbieter für Namespaces, die die Serialisierung mithilfe der Sperrung 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 im ADSI-Schemacontainer dar. Dies erfordert, dass Eigenschaftennamen innerhalb jedes Schemacontainers eindeutig sind. Der Anbieter muss sicherstellen, dass keine Namenkollisionen vorhanden sind.

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. Dadurch werden alle Eigenschaften eines Objekts durch IDispatch und die IADs::Get, IADs::Get, IADs::GetEx, IADs::P ut und IADs: :P utEx-Methoden bereitgestellt.