About three years ago, I wrote a blog post titled "Why I hate developing for Microsoft Platforms". At the time, I focused primarily on difficulties with MSDN, particularly as it relates to older technologies. I complained about what I perceived to be syntactic oddities in VBScript, and trotted out some of my long-time complaints with Windows GUI Programming.
Fast forward 3 years, and the GUI programming complaint has diminished, somewhat. Windows Presentation Foundation and Silverlight both use more declarative methods of creating UI via an XML-analogue, and support solid, run-time skinning. They're a great step forward for UI design on Windows.
The other issues? Well, I still have gripes about those.
But then, I was reading 97 Things Every Software Architect Should Know on my new Nook (of which an in depth review will be forthcoming in a couple of weeks. Initial impression is mostly positive), and the second chapter, by Neal Ford, entitled "Simplify Essential Complexity; Diminish Accidental Complexity" contained the following passage that really spoke to me.
Prefer frameworks derived from working code rather than ones cast down from ivory towers...Cast a wary eye on vendor-driven solutions. They may not be inherently bad, but vendors often push accidental complexity.
Ultimately, this is the problem that I've always had working with Microsoft Technology, particularly recently. Microsoft works really hard to solve problems that aren't theirs. Workflow Foundation is a perfect example. Launched with .NET 3.5, it sounded like a great solution to a problem we were having at work. However, we quickly ran into problems. The tools began to crawl on complex workflows, and they were pretty much necessary to define the workflow. Creating a workflow from code certainly appeared prohibitive.
Then there was the upgrade path. Workflow instances, by default, could be modified in real time, but you could only load a workflow instance into a complied version of a class that hadn't changed. There was no clean way to upgrade, in place, a running workflow instance to a new version. And it is very difficult to build a new instance of a workflow, even if you don't store any important data in the instance.
Building workflows is complicated, and working with them for anything other than relatively simple and short tasks in WF 3.0 is a bit painful.
I think Microsoft agreed, since they pretty much entirely replaced it in WF 4.0. They even moved the code to a new namespace. I had the opportunity to meet Glenn Block at Portland Code Camp, a Microsoftie who worked on the Microsoft Extensibility Framework (which sounds pretty awesome, but then, Microsoft is actively using it) and is now working on Microsoft's REST team. He admitted that Microsoft does occasionally create APIs, based on customer feedback, yes, but not enough customer feedback.
Ultimately, I think it comes from the fact that they are creating solutions for other people's problems, not their own. I see this in ASP.NET MVC fairly often as well. Creating a Form, where you want to declare a custom ID? The FormExtensions.BeginForm extension method for the HtmlHelper goes from requiring 0 or 2 (depending on the action you're form calls) arguments to at least four. But then, it's really common in the MVC APIs to take route values either as anonymous objects or RouteValueDictionaries. The API would be a lot simpler if it only took RouteValueDictionaries, because then plain anonymous objects could be reserved for the Html Attributes you want to add. Or a Dictionary type could be created for the Html Attributes. It's a bit of type-glut, perhaps, but the API (and specifically the number of required parameters) can go down quite a bit.
I think ultimately, this is why I tend to prefer Open Source APIs (like GTK+, Django or YUI). For most, functions generally aren't added until a need is demonstrated, and with speedy release cycles, this functionality can be made available pretty quickly once it's been identified (and contributed). But even if you can demonstrate your own need, it generally requires more demonstration to make it available as a core feature.
It takes solid design to produce the core of a good API. That nugget on which everything else is built. Beyond that core, it seems easiest to slowly evolve the rest of the API based on real needs. And the only way to really judge those needs are to be building something real with them. ASP.NET MVC has improved dramatically into 2.0 (and now 3.0), based on feedback that team's been receiving since the original CTPs, well before the release of 1.0.
I guess it seems the best way to approach API design may well resemble my feelings on law. The moment someone says there ought to be an API call for X, they may well be wrong.