I have to agree with Neil, but I have a variation to suggest.

Traditional DI/IOC containers are fundamentally static singletons and
should be treated as such.

That being the case, continue to use "spring" or "guice" or whatnot inside
your bundle.

However, associate it with any single DS component which acts as it's
controller. This already happens in every use case of those frameworks to
date.

- whenever you use spring, guice, CDI or whatever there is one single
moment when suddenly the entire context is ready, just like if you
instantiated a single class. Destruction is the same (in fact these are
almost always implemented as a huge synchronized operation).

The technique I'm suggesting allows you to still "benefit" from isolated
internal wiring, while also benefiting from services around it's outer
edges.

But don't expect the wiring to suddenly be "dynamic" because it obviously
will never be. When the controller DS component can no longer be satisfied
then you must tear it down which is exactly what you'd have to do outside
osgi anyway.

FYI, this should be extremely simple to do as a DS component (spring
example):

(never tried any of this, but in theory...)

-  create a DS component that extends
org.springframework.context.annotation.AnnotationConfigApplicationContext
- which calls it's scan(packages) method during @Activate
- but first it could create an ApplicationContext from all it's @Reference
"beans" and set it as the parent context
- call refresh()
- the main context is now ready
- publish any "beans" matching whatever logic you please as services
- reverse the process on @Deactivate

Repeat this pattern for any traditional DI/IOC container.

Thinking about it, you could even gain some dynamics in your beans if you
have for instance a managed collection using a complex dynamic reference
like:

    @Reference(
        cardinality = ReferenceCardinality.MULTIPLE,
        policy = ReferencePolicy.DYNAMIC,
        policyOption = ReferencePolicyOption.GREEDY
    )
    protected void setSomething(Something something) {
        this.somethings.add(something);
    }

    private final Collection<Something> somethings = new
CopyOnWriteArrayList<>();

and just supply the collection as a bean (wrapped in unmodifiable) in the
parent context.

Almost sounds reasonable.

- Ray



On Thu, May 21, 2015 at 11:28 AM, Neil Bartlett <njbartl...@gmail.com>
wrote:

> Hi Simon,
>
> You’re essentially correct, at least in the difference between Blueprint
> and DS. I can’t comment on DM since I don’t use it. However the wording of
> your email implies that this is a failing of DS and a win for Blueprint,
> whereas I tend to see it as the exact opposite!
>
> For me, Blueprint does not successfully hide the OSGi lifecycle but adds
> an additional lifecycle within the OSGi one. For example, Blueprint
> containers cannot be activated until all of the mandatory references within
> the container are satisfied… but there can be beans in the container that
> are fully satisfied because they do not need the unsatisfied references.
> Why not start just those beans? It doesn’t make sense. Still, if that is
> the Blueprint policy then you would at least expect it to be consistent, so
> that when a mandatory reference from an active container becomes
> unsatisfied, the container will be deactivated. But Blueprint doesn’t
> actually do this, it merely puts the container into a kind of suspended
> state. Again it doesn’t make sense.
>
> Well actually it makes sense when you realise that Blueprint represents a
> legacy container concept that has been crowbarred to fit into OSGi…
>
> Regarding your last point; you are right that components (beans if you
> prefer) often need to use other objects from within the bundle, and those
> objects should not escape from the bundle. In DS I find it perfectly
> acceptable to instantiate these components with the “new” keyword. I don’t
> really see why I would want to use a type-unsafe XML descriptor to do this
> rather than Java code.
>
> Regards,
> Neil
>
> > On 21 May 2015, at 15:52, Simon Kitching <si...@vonos.net> wrote:
> >
> > Hi,
> >
> > In blueprint it is possible to define arbitrary objects (beans) which
> are not published to the service registry but nevertheless can be injected
> into other beans.
> >
> > AFAICT, in both declarative-services and felix-dm, the only objects that
> can be injected are references to services from the OSGi registry. Is this
> correct?
> >
> > I understand that with DS and DM, components follow the standard OSGi
> lifecycles, in contrast to the Blueprint approach of "hiding" the
> lifecycle. In particular, in DS and DM when a component's mandatory
> dependency is deregistered then the component is also deregistered (which
> can cascade further). And the kind of tracking of dependencies required to
> make this happen is exactly what a service registry does.
> >
> > However it's common for a bundle to have objects which are purely
> internal implementation details of the bundle, and are not for external
> use. Yet as far as I can see, in order to manage them with DS or DM, such
> internal objects need to be published into the global service registry -
> just to be able to then inject them back into components in the same bundle.
> >
> > Have I misunderstood something?
> >
> > Thanks,
> > Simon
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscr...@felix.apache.org
> > For additional commands, e-mail: users-h...@felix.apache.org
> >
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscr...@felix.apache.org
> For additional commands, e-mail: users-h...@felix.apache.org
>
>


-- 
*Raymond Augé* <http://www.liferay.com/web/raymond.auge/profile>
 (@rotty3000)
Senior Software Architect *Liferay, Inc.* <http://www.liferay.com>
 (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance <http://osgi.org> (@OSGiAlliance)

Reply via email to