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