When I first tried to get my mind around LDAP via the ADSI libraries in Windows NT 4.0, I quickly convinced myself that "L" in LDAP (which of course stands for "lightweight") was an ironic joke. Then I heard about X.500, and not a programming day has gone by since in which I haven't silently thanked the University of Michigan for getting us all off the hook for implementing DAP (go Wolverines!)
Of course, that didn't make the task at hand any easier. Learning LDAP via ADSI was a daunting task for me - likewise for just about every other developer I've worked with. I think this is because at its core, ADSI is a library designed to support administrative tools (consoles, scripts, etc.) and thus was *not* designed with middle-tier component development in mind. If you attempt to use ADSI in the middle-tier (or .NET 1.1's System.DirectoryServices classes, which provide a managed wrapper over ADSI) and have a need to authenticate a large number of identities, you'll quickly find out why.
Unfortunately, there are situations in which only LDAP will do in the middle-tier, and unfortunately, there were limited options available on the .NET 1.1 platform. To achieve high-scale and high-performance there, I ended up writing directly to WLDAP32.DLL, which is the library ADSI uses to make LDAP calls. Techniques for calling WLDAP32.DLL from the world of managed code are poorly documented and unpleasant in the extreme (and aren't even listed on http://www.pinvoke.net), but once I got them working, they proved to be ripping fast and rock solid. Still, I don't envy anyone attempting to go this route.
And thankfully with .NET 2.0, you don't have to.
The System.DirectoryServices.Protocols namespace now includes proper LDAP classes suitable for use in the middle-tier which provide all the functionality present in WLDAP32.DLL. When it absolutely, postively has to be LDAP in the middle tier, this is a godsend for .NET developers. Because after all, in its essential form, LDAP really is pretty simple and lightweight. Directory objects have attributes, and attributes have values, and that sort of hierarchical relationship should be second nature in the era of XML.
Maybe I should start silently thanking the .NET Framework team every programming day (go Seahawks?)