jbee / purejin

java dependency injection through code
http://jbee.github.io/purejin/
Apache License 2.0
85 stars 9 forks source link

ExtensionPoints #26

Closed jbee closed 9 years ago

jbee commented 12 years ago

ExtensionPoint as a set of uniform values - all of them arise from binds. Something like this is used for service classes.

The extension point should allow to handle those kind of need better and more independent from the builder. the builder gets convenient support for ExtensionPoints. A user can always add more of those points.

static final ExtensionPoint<Class<?>> SERVICE_CLASSES = extensionPoint(Class.class, "serviceMethod"); 

The example shows that a point could be a constant having a id String and a element type. The usage could look like this:

extend(SERVICE_CLASSES, MyServiceClass.class); 

So the signature of the above method looks like

<T> void extend(ExtensionPoint<T> point, T extension); 

Or for better encapsulation the point has methods that accept a Binder

void extend(Binder binder, T extension);
// invocation
SERVICE_CLASSES.extend(binder, MyServiceClass.class);

When loading all bound elements it could look like:

Class<?>[] serviceClasses = SERVICE_CLASSES.extensions(injector); 

Like this the class becomes a nice util.

jbee commented 12 years ago

Interceptors should be something that could make use of extension points.

jbee commented 12 years ago

It is always about a set of classes. Sometimes there is a constraint that all should extend a base-type. Maybe this could be done more like Bundles and Modules. Something like the service-classes is a Extensions.

jbee commented 12 years ago

The benefit of a Class based extension is that an extension is defined by a consumer and used by several contributors. This can be understood by the bootstrapper whereby contributions to not installed extensions will not even make their way into a binding.

jbee commented 12 years ago

Most likely it will be wise to use enums here too. While Extension is an interface implemented by them.

enum ServiceMethodExtension implements Extension<Object> { }

Here the generic is Object because there is no limitation what classes could be used. In case of a Interceptor it would be

enum ServiceMethodInterceptorExtension implements Extension<Interceptor> { }

Via reflection the type argument on Extension can be read. No further methods are necessary. The constants of the enum can be used to allow groups of something like here e.g. Interceptors used before and others used after. When no groups are needed just one constant is used. When add an actual extension class just the enum class is an alias to the first constant.

extend(ServiceMethodInterceptorExtension.class, LoggingInterceptor.class);
//or
extend(ServiceMethodInterceptorExtension.BEFORE, LoggingInterceptor.class);
jbee commented 12 years ago

It should be possible to narrow down when to use a extension (packages, types - same as binds in general). Maybe it works already ?!

jbee commented 9 years ago

finally plug-into has solved this nicely. (v0.8)