hivemind-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Knut Wannheden" <knut.wannhe...@gmail.com>
Subject Re: comments / questions on hivemind 2.0 branch
Date Thu, 02 Nov 2006 14:07:57 GMT
Achim,

On 11/2/06, Achim Hügen <achim.huegen@gmx.de> wrote:
> Knut Wannheden schrieb:
> >
> > - The ObjectProvider interface is in the XML source module. I believe
> > this should be part of the framework. We might for example also want
> > to use that in the annotation support to inject objects into
> > parameters of methods creating service implementations.
> Yes and no. There might be a use case that justifies putting the
> ObjectProviders
> in the framework but I don't regard annotations as one.
> I wouldn't do anything textual in annotations which could be implemented
> in pure java without any extra work. Let's have a look at the
> current object providers:
> ClassObjectProvider: -> trivial in java code
> ConfigurationObjectProvider -> just call getConfiguration() in an
> annotated module
> ObjectInstanceProvider -> trivial in java code
> ServiceObjectProvider -> just call getService() in an annotated module
> ServicePropertyProvider -> just call getService() and then any getter method
> BeanFactoryProvider -> create the bean manually or call a factory method
>
> For the moment it could stay in the xml module and if needed we could
> move it without breaking compatibility?
>

I must say I still haven't looked at an example of how your annotation
support is used. And maybe I've studied the Tapestry 5 IOC framework
(http://tapestry.apache.org/tapestry5/ioc/index.html) too hard. But
IMHO it looks very good.

You say that you would simply call getService(). Is that method called
on parameter that's always passed or is it an inherited method? This
is solved very cleanly in Tapestry 5 IOC where a module class neither
has to inherit from another class nor are there any special
parameters. Take a look at these pages to see how object providers are
used: http://tapestry.apache.org/tapestry5/ioc/module.html and
http://tapestry.apache.org/tapestry5/ioc/service.html.

Also I've noticed that quite a few of the features users can't find as
out-of-the-box features in HiveMind (just like the one I answered
earlier today on the user list) can often be solved by a custom object
provider. Thus I think these would be really useful to have in the
framework or another module other than xml. Maybe the library.

> > - On the other hand I wonder if instead the SymbolSource classes along
> > with the symbol expansion code should be moved into the XML module.
> > They are used to resolve Ant style ${}-properties in the XML
> > descriptors. Do we want to support these in other module descriptors
> > (e.g. annotation based Java classes) also?
> I regard it as another simple configuration mechanism for an application.
> But there may be better (and even typed) ways to read system properties etc.
> My first attempt to break the deep integration with the registry failed
> but if we decide to move it to xml I could make another try.
>

There are really two separate features we should consider. The symbol
sources on the one hand and the symbol expansion on the other. IMHO we
should at least try to move the symbol expansion into the schema
processing of the xml module.

> > - I noticed the ServiceImplementationFactory is in the xml module.
> > Maybe we could also move the ServiceInterceptorFactory to the xml
> > module. Although I think some of its implementations (really only the
> > LoggingInterceptorFactory) should remain in the framework module which
> > would mean it can't implement the interface anymore. But IMHO that's
> > OK, because the first thing that's done in the implemented interface
> > method is to cast the Object parameter to a List. That could be done
> > by an adapter implementation in the xml module.
> That's exactly how it should be done. I hope we can do it during
> the redesign of the interceptor construction, when createInterceptor
> will return an interceptor object.

OK, glad we find something we can agree on ;-)

> > - Now some comments on the registry construction API. I believe an
> > interface based registry construction API would allow for more
> > flexibility in the implementations. For example you'd have to
> > possibility of refactoring the existing *Descriptor classes in the XML
> > module to implement these interfaces instead of define a mapping. As
> > another example an implementation could chose to have a single object
> > implement two interfaces (e.g. ServicePointDef and ImplementationDef).
> > Further we could then also remove OrderedServiceInterceptorDefinition
> > and simply note that an implementation class can implement the
> > Orderable interface if ordering is required.
> One problem prevented me from conversion to interfaces at all.
> Configurations like ServiceModels, EagerLoad, Startup etc. are defined
> in the core framework. Afterwards they get schemas assigned
> from the xml module. They are a little ambivalent.
> To hold the schema information they would have
> to be represented by a xml specific implementation of
> ConfigurationPointDefinition
> which is not available in the framework when they get constructed.
> Natures (or better decorators) solve this problem.
>

Maybe we could also drop the support for contributing to these
configurations using XML. OK, I know this contradicts what I wrote
about backwards compatibility in the other thread, but maybe that
would be OK. I'd like to point out that Howard changed how the eager
loading works in Tapestry 5 IOC. The ServicePointDef simply has a
boolean getEagerLoad() method. How about that?

> Like you mentioned below only the xml module uses natures in the moment.
> This means on the other hand that all the overhead of the separation
> between interfaces and implementations would be done for that
> single case. Whereas natures doesn't hurt since you are not forced
> to use them.
>
> The definition classes doesn't contain any logic besides consistency
> checking.
> In the meantime I regard it as perfectly valid to use plain beans for them.
> The java/xml/annotation-specific parts are done in the constructors which
> are realized as interfaces.
>

I still quite strongly believe that defining the API as a set of
interfaces would be worth the effort. And as far as natures are
concerned I can see that they can be used for many different things
although they do add some complexity. But as we've already previously
discussed I really think that we should call them adapters instead of
natures. Maybe we should even let all *Def types allow to have
adapters.

> > - Also I think the API could be simplified by removing the distinction
> > between resolved and unresolved extensions. That would make the
> > registry builder responsible for all resolutions.
> During the construction of the registry a complete object graph of
> definition
> items is build up where all unresolved extensions get resolved and placed
> into the referenced extension points. It is quite convenient to use the same
> data structure here that were used for the definition.
> The RegistrySerializer (though far from being usable) uses the graph too.
> Moreover it is convenient and IMHO more intuitive to attach an
> implementation
> defnition directly to an service definition instead of putting it
> unresolved into
> the module.
>

If it always were the case that an extension gets attached to its
definition then I agree that your design is more intuitive. But since
that's not always the case, especially in the case of configuration
contributions, then I think that consistency and simplicity should
outweigh.

Further I don't think we need to provide for much convenience in the
API. For users who'd like to define modules using pure (non annotated)
Java code to define registry constituents we could provide a Java
implementation of the API with all of this convenience built in.

I hope we'll be able to find some common ground and not end up
disagreeing on everything.

Regards,

--knut

Mime
View raw message