Skip to content

Add convenience methods to configuration builders that don't need a configuration #4171

@hjohn

Description

@hjohn

Enhancement Description

When users use builders for declarative configuration, they often don't need the configuration parameter. It would be nice if builders would accept the value the user wants to provide directly. This makes the configuration code more readable, and less nested, and will more often allow for method references.

For example:

        EventSourcedEntityModule<String, Account> module = EventSourcedEntityModule.declarative(String.class, Account.class)
            .messagingModel((c, model) -> model.entityEvolver(evolver()).build())
            .entityFactory(c -> EventSourcedEntityFactory.fromIdentifier(Account::new))
            .criteriaResolver(c -> (id, ctx) -> EventCriteria.havingTags(Tag.of("account", id)))
            .build();

Could become:

        EventSourcedEntityModule<String, Account> module = EventSourcedEntityModule.declarative(String.class, Account.class)
            .messagingModel(model -> model.entityEvolver(evolver()).build())
            .entityFactory(EventSourcedEntityFactory.fromIdentifier(Account::new))
            .criteriaResolver((id, ctx) -> EventCriteria.havingTags(Tag.of("account", id)))
            .build();

This reads a lot better in Java, and only takes adding a default method to the builders. Especially the 2nd and last example (with the double lambda) are much improved here.

Current Behaviour

One must always pass a Lambda that accept the configuration parameter (in case it is needed).

Wanted Behaviour

Add an overload that doesn't require the configuration lambda.

Possible Workarounds

None

Example implementation

Note the new default method:

    interface EntityFactoryPhase<ID, E> {

        /**
         * Registers the given {@link ComponentBuilder} of an {@link EventSourcedEntityFactory} as the factory for the
         * event-sourced entity being built. This factory is responsible for creating the event-sourced entity of type
         * {@code E} based on the entity's type, an identifier of type {@code I}, and optionally an
         * {@link EventMessage} if the stream is non-empty.
         *
         * @param entityFactory A {@link ComponentBuilder} constructing the {@link EventSourcedEntityFactory} for the
         *                      event-sourced entity.
         * @return The {@link CriteriaResolver} phase of this builder, for a fluent API.
         */
        CriteriaResolverPhase<ID, E> entityFactory(
                @Nonnull ComponentBuilder<EventSourcedEntityFactory<ID, E>> entityFactory
        );

        default CriteriaResolverPhase<ID, E> entityFactory(EventSourcedEntityFactory<ID, E> entityFactory) {
            return entityFactory(c -> entityFactory);
        }
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No fields configured for Enhancement.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions