On 03/22/2012 01:56 PM, Noel Grandin wrote:
How do I decide whether to change the constructor to take
XComponentContext or XMultiComponentFactory?

It is always XComponentContext that you want to move around, never XMultiComponentFactory.

In the old days, there was just XMultiServiceFactory, used for two different things:

* A global XMultiServiceFactory (passed around), through which client code can instantiate services it wants to use.

* Each service implementation itself has some XMultiServiceFactory (or XSingleServiceFactory; often hidden within the implementations behind some helper foo), through which the global XMultiServiceFactory obtains instances of the given service. When the global XMultiServiceFactory instantiats a service, it passes a ref to itself to that service, so that that service in turn has a global XMultiServiceFactory where /it/ can instantiate further services from, if necessary.

With the introduction of the component context, things changed slightly:

* There is now a global XComponentContext. It contains an XMultiComponentFactory (XComponentContext.getServiceManager) through which client code can instantiate services it wants to use. (And new-style service constructors hide this getServiceManager()->createInstance(...) stuff.)

* An XMultiComponentFactory is like an XMultiServiceFactory, except it allows to pass on the (global) XComponentContext. (And the implementation of the global XMultiComponentFactory also still supports the XMultiServiceFactory interface, for backwards compatibility.)

* Service implementations nowadays should have an XMultiComponentFactory (or XSingleComponentFactory) through which the global XComponentContext/XMultiComponentFactory can create instances of them (as that way those instances receive the global XComponentContext for internal use). Again, there is helper foo to do just that (cppu::component_getFactoryHelper; see configmgr/source/services.cxx for a clean example of how such a factory for various services and singletons implemented within one library should look like). For historic reasons, lots of service implementations still use the old way, though.

As a quick fix, you can pass comphelper::getProcessComponentContext()
(#include "comphelper/processfactory.hxx") into create(), but you
unfortunately cannot even commit that, as it violates module
dependencies (comphelper depends on ucbhelper, so ucbhelper cannot
depend on comphelper). The right fix is to change the
ResultSetImplHelper constructor and adapt all its uses accordingly.

For code not below comphelper that only has a global XMultiServiceFactory at hand, but rather needs an XComponentContext (e.g., to pass it into a new-style service constructor), comphelper::getComponentContext (comphelper/processfactory.hxx) can be used to convert the former into the latter. (But the best fix, of course, is to change all places that currently have a reference to the global XMultiServiceFactory, to instead have a reference to the global XComponentContext.)

Stephan
_______________________________________________
LibreOffice mailing list
LibreOffice@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice

Reply via email to