Date: prev next · Thread: first prev next last
2012 Archives by date, by thread · List index


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

Context


Privacy Policy | Impressum (Legal Info) | Copyright information: Unless otherwise specified, all text and images on this website are licensed under the Creative Commons Attribution-Share Alike 3.0 License. This does not include the source code of LibreOffice, which is licensed under the Mozilla Public License (MPLv2). "LibreOffice" and "The Document Foundation" are registered trademarks of their corresponding registered owners or are in actual use as trademarks in one or more countries. Their respective logos and icons are also subject to international copyright laws. Use thereof is explained in our trademark policy.