You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@felix.apache.org by "Pierre De Rop (JIRA)" <ji...@apache.org> on 2015/10/30 10:23:27 UTC
[jira] [Commented] (FELIX-4689) Create a more fluent syntax for the
dependency manager builder
[ https://issues.apache.org/jira/browse/FELIX-4689?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14982213#comment-14982213 ]
Pierre De Rop commented on FELIX-4689:
--------------------------------------
Hello Christian,
First, I apologies for not having looked into this issue sooner.
It's an old issue that you posted from a long time ago and I'm sure you don't like seeing your issue lagging ...
So, the fact is that a couple of month ago, from my side, I also worked on a new builder API.
To do so, I inspired a lot from the suggestion made by Paul (that is: provide an external builder outside the current DM api, in a new module), and I aslo inspired a lot from your patch.
I also added some support for java8, especially using some type-safe java8 constructs like method references, lambdas, some new features to make life easier, and so on).
So, I think we have to merge our work. this week-end I will try to attach the work I did, and order to compare.
I'm just giving here one quick example, where a "Provider" service is instantiated with a ProviderFactory. The ProvidedFactory is instantiated lazaly using a ::new, and there is also a dependency on a LogService that is injected using a type-safe method reference. The start callback is also specified using a method ref.
The "component" function takes a lambda that is given a Component object. And that lambda must be supplied by the Activator.
When you define a service dependency, you also pass a lambda (see "withService") that is given a ServiceDependency object ("srv"), and you have to supply the lambda that initializes it:
{code}
public class Activator extends DependencyBuilderActivator {
@Override
public void init() throws Exception {
component(comp -> comp
.provides(Provider.class)
.factory(ProviderFactory::new, ProviderFactory::create)
.withService(LogService.class, srv -> srv.required().onAdd(ProviderImpl::set))
.onStart(ProviderImpl::start));
}
}
{code}
So, this WE, I'll try to attach my work.
The problem is that I'm currently working on FELIX-4955 ("DS based on Dependency Manager"), and I would like to finish this before starting to work on your issue. Anyway I'll try to attach my java8 builder version this we, and will get back on this issue in a couple of weeks (but I need 4 or 5 weeks to first finish FELIX-4955).
Cheers;
/Pierre
> Create a more fluent syntax for the dependency manager builder
> --------------------------------------------------------------
>
> Key: FELIX-4689
> URL: https://issues.apache.org/jira/browse/FELIX-4689
> Project: Felix
> Issue Type: Improvement
> Components: Dependency Manager
> Reporter: Christian Schneider
> Attachments: FELIX-4689-1.patch
>
>
> I wonder if the DependencyManager API could be made a bit more fluent.
> Technically it already uses the fluent builder pattern
> but all the builder verbs still look a lot like traditional setters.
> I know what I propose is mostly syntactic sugar but I think the result
> looks more readable and crisp. See below for some ideas.
> There is the concern about auto adding the component() to manager as it would acrivate the not fully configured component. We could perhaps overcome this by adding the component to a list of pending components first and then moving them to the active components after the init method.
> The camel DSL solves this similarly.
> This is from samples.dependonservice:
> public void init(BundleContext context, DependencyManager manager)
> throws Exception {
> manager.add(createComponent()
> .setImplementation(DataGenerator.class)
> .add(createServiceDependency()
> .setService(Store.class)
> .setRequired(true)
> )
> .add(createServiceDependency()
> .setService(LogService.class)
> .setRequired(false)
> )
> );
> }
> Why not make it look like this:
> public void init(BundleContext context, DependencyManager manager)
> throws Exception {
> component()
> .implementation(DataGenerator.class)
> .add(serviceDependency(Store.class).required())
> .add(serviceDependency(LogService.class))
> );
> );
> }
> component() could create and add the component.
> Or for configuration:
> public void init(BundleContext context, DependencyManager manager)
> throws Exception {
> manager.add(createComponent()
> .setImplementation(Task.class)
> .add(createConfigurationDependency()
> .setPid("config.pid")
> // The following is optional and allows to display our
> configuration from webconsole
> .setHeading("Task Configuration")
> .setDescription("Configuration for the Task Service")
> .add(createPropertyMetaData()
> .setCardinality(0)
> .setType(String.class)
> .setHeading("Task Interval")
> .setDescription("Declare here the interval used to
> trigger the Task")
> .setDefaults(new String[] {"10"})
> .setId("interval"))));
> }
> could be:
> public void init(BundleContext context, DependencyManager manager)
> throws Exception {
> component().implementation(Task.class)
> .configuration("config.pid")
> .add(meta("Task Configuration)
> .description("Configuration for the Task Service")
> .add(property("interval")
> .cardinality(0)
> .type(String.class)
> .heading("Task Interval")
> .description("Declare here the interval used
> to trigger the Task")
> .default("10"))
> }
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)