Well, of course you don't _need_ it. You can always go and parse the extension string yourself, then call LoadLibrary() and GetProcAddress() to manually setup pointers to the extension functions etc. The point is that you don't have to care about any of that crap when using DirectX. Bear in mind, this is just one example.
In DX you have to care about version and capability bits (up to DX9) or speed (same caps, some may be implemented in software, DX10+). Same thing in slightly different way.