Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [sisu-dev] EntryListAdapter and notifications

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
To change your delivery options, retrieve your password, or unsubscribe from this list, visit


Back to the top