Hi Stuart,
Looks great, thank you.
As a simpler solution I was imagining
the injected lists to extend java.beans.PropertyChangeSupport or similar.
That would have been sufficient for my simple use case, but the mediator
looks way more powerful.
The only downside I can find in the mediator
is that it implies a compile-time dependency on Sisu: so far I have been
able to encapsulate all Sisu dependencies in my custom extender while all
the remaining of the application code just uses JSR 330.
GianMaria.
From:
Stuart McCulloch <mcculls@xxxxxxxxx>
To:
Sisu project developer
discussions <sisu-dev@xxxxxxxxxxx>
Date:
21/11/2014 14:26
Subject:
[SpamSentinel]
Re: [sisu-dev] EntryListAdapter and notifications
Sent by:
sisu-dev-bounces@xxxxxxxxxxx
Hi GianMaria,
When you inject a collection in Sisu the concrete type
injected will be one of the collection adapters, such as EntryListAdapter.
The job of this adapter is to provide the appropriate API and behaviour
on top of the underlying Iterable<BeanEntry> which is by design lazy.
This laziness means injected collections are best suited for situations
where you get an external trigger and want to see what’s registered at
that point in time, or are only interested in a subset of the collection.
For a listener type approach, where you want notification
of entries as they come and go, I’d recommend using the Mediator pattern:
http://eclipse.org/sisu/docs/api/org.eclipse.sisu.inject/reference/org/eclipse/sisu/Mediator.html
The difference between these two approaches can be seen
in the following example, where there's a Display and zero or more Widget
components to display:
public interface Display {
void show(Widget widget);
void hide(Widget widget);
}
If you only need to update the display occasionally (for
example triggered by an external event) or you want to batch updates then
you could do something like this:
@Named
public class TriggerExample {
@Inject
Display display;
@Inject
List<Widget> widgets;
public void update() {
for (Widget w : widgets) {
display.show(w);
}
}
}
The downside is that this isn’t reactive and you'll need
additional book-marking to know when to hide widgets, or avoid showing
the same widget more than once.
Contrast this with the following Mediator example, which
automatically gets informed of component entries as they come and go from
the application:
@Named
public class MediatorExample
implements Mediator<Named, Widget, Display>
{
public void add(BeanEntry<Named, Widget>
entry, Display display) {
display.show(entry.getValue());
}
public void remove(BeanEntry<Named, Widget>
entry, Display display) {
display.hide(entry.getValue());
}
}
The general idea behind Mediators is to provide a way
for applications to get notified by Sisu without having Sisu API leak into
the rest of your code. It also avoids having to know about the surrounding
container because Sisu will automatically create Mediators and associate
them with the specified type of watcher (and dispose of them when the watcher
becomes unreachable). But if you prefer to do this programatically then
you can always use the BeanLocator API to register your mediators.
We use Mediators in Nexus whenever we need to actively
update or react to changes as bundles come and go, and it’s been working
well as a design pattern.
--
Cheers, Stuart
On Friday, 21 November 2014 at 10:32, gian.maria.romanato@xxxxxxxxxxxx
wrote:
Hi,
I am using Sisu 0.2 in an OSGi application and I am happily taking advantage
of its capability of injecting components into dynamic lists that get updated
by Sisu as bundles come and go.
The more we use Sisu, the happier we
are with it, at a point that we are considering using it for some of the
responsibilities that for historical reasons were delegated to the Equinox
Registry, which is also used in my application.
For example, the Equinox Registry was
often used to be able to contribute configuration pieces that are subject
to the bundle lifecycle. In this context everything works fine, but to
consume the contributed configuration one has to deal with the IExtensionPoint,
IExtension and IConfigurationElement classes of the Equinox Registry API,
which remind of low-level XML DOM manipulation.
I can imagine someone to prefer a more
object oriented approach: for example, instead of declaring an extension
point, one could define an abstract configuration bean. Those who want
to contribute to the extension point would just need to subclass the abstract
bean, call setters in its default constructor to define the configuration
values, and make sure the new class is annotated @Named. At this point
the configurable subsystem could just use a @Named List< AbstractConfigurationBean>
to be injected with all available configuration beans by Sisu.
There is only one thing that the Equinox
Registry would still do better in this case: it's ability to notify change
events as items come and go due to their declaring bundle coming and going.
If I am not mistaken, when Sisu injects
a list, the list type if EntryListAdapter. Do you think it would make sense
to extend it so that it allows to add/remove listeners that get notified
when list items are added/removed?
GianMaria.
_______________________________________________
sisu-dev mailing list
sisu-dev@xxxxxxxxxxx
To change your delivery options, retrieve your password,
or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/sisu-dev
_______________________________________________
sisu-dev mailing list
sisu-dev@xxxxxxxxxxx
To change your delivery options, retrieve your password, or unsubscribe
from this list, visit
https://dev.eclipse.org/mailman/listinfo/sisu-dev