Despite some trolling, pfremy had a few valid points in my opinion:
- GNOME isn't very well componentised. My personal feeling is that this is a fault of bonobo being so complicated to use. Sure, it might not be that bad in python or whatever, but in C it is just a horrid nightmare. 
- In an ideal world, Nautilus would have been properly designed such that writing a File Selection dialog could have used a Nautilus view component.
A few of the responses to pfremy claimed that gnome-vfs is used by gnome applications for file access. Since when? I'm not saying that apps shouldn't use it, but I was just not aware that it was being done. Evolution certainly doesn't use it for file i/o. The mailer used to use it for http access, but that has been removed in favour of soup mostly because we had a lot of problems (CORBA reentrancy, yay). I believe some other components still use it for ftp/http/etc access though (like wombat or the calendar or something).
 CORBA by itself is pretty complicated in C, the APIs are horrible. It just seems to me that it introduces more complexities than it solves and Bonobo on top of that seems to cause no end of pain to developers. Well, this is true at least on the Evolution team. But how many other projects use Bonobo? There are like 5 or 6 total. I think this is mostly because developers get scared away by it. I know I am.
Now, I'm no expert, but I think a component system could be made a lot simpler. Why not simply use something as symple as dlopen()? Let me elaborate:
First, we'll still need something similar to oaf - a way to query which .so's implement which interfaces and to request an object that implements the required interfaces. This could be done fairly simply: Each "component" .so can have a xml file or some other file format that describes its interfaces. The library that handles the querying could load these xml files and provide the following interfaces for querying:
get_component_by_name (const char *name)
list_components_implementing_iface (const char *iface)
get_default_component_implementing_iface (const char *iface)
There's 2 reasons for using the list(). The application may have an order of preference (ie, it may know about a few components that implement the iface it needs, but might have a preference as to which one it uses assuming that the module is available?). Second usage would be something like the Evolution Shell - it might query for all components implementing the evolution-shell iface so that it may load them all (this would include the mailer, the calendar, the addressbook, the summary, and possibly others). The application could then use get_component_by_name () to essentially dlopen() th library.
This makes writing components as easy as writing a shared library. It can't get much simpler.
Of course, there's still the problem of menu merging... but we could make that a required function for all modules have to implement. And it wouldn't even necessarily need to use xml like bonobo-ui and kparts do, you could just have a function that you pass in a menubar to (okay, this might not be ideal since we may want to merge toolbar stuff, and possibly add right-click menu item,s and so on).