Hi,
There have been a few discussions in the recent past about factoring
out the dependency injection logic used by the BuilderFactory and make
it available for reuse. The dependency injection logic should be
reusable by other service and interceptor factories and possibly also
other user code.
I have been playing with this a little bit and would like to discuss
my results with you. Quite possibly I'm not the only one who has been
playing with this and most certainly a few of you have good ideas on
how this should be implemented. So please take a look at what I've
done and let's see if anything comes out of it.
First I'd like to more precisely define what the very core of the
dependency injection logic should do and shouldn't do. IMO the DI
logic should be able to both perform constructor based dependency
injection (CBDI) and setter based dependency injection (SBDI) given a
specification on the dependencies. This means that autowiring would
have to be worked out at a higher level by "compiling" the dependency
specification.
At the DI logic level I've come up with something like this (details left out):
class DependencyInjector
{
// returns an instance of clazz configured as specified in spec
(CBDI and SBDI)
public Object createInstance(Class clazz, DependencySpecification spec) {...}
// injects dependencies into object as specified by spec (only SBDI)
public void injectDependencies(Object object,
DependencySpecification spec) {...}
}
abstract class DependencySpecification
{
// determines whether the given constructor satisfies this
specification (for CBDI use)
public abstract boolean isSatisfiedBy(Constructor c);
// returns a new compound specification
public DependencySpecification and(DependencySpecification other) {...}
// determines whether the given other specification conflicts with
this specification
public abstract boolean conflictsWith(DependencySpecification other);
}
class ConstructorSpecification extends DependencySpecification
{
public static final ConstructorSpecification DEFAULT_CONSTRUCTOR_SPEC = ...;
public ConstructorSpecification(Class type, Object value) {...}
public ConstructorSpecification(Class type, Object value, int position) {...}
}
class SetterSpecification extends DependencySpecification
{
public SetterSpecification(Class type, Object value) {...}
public SetterSpecification(Class type, Object value, String
propertyName) {...}
}
So the equivalent of:
Foo bar = new Foo(42, "foo");
bar.setName("bar");
is for example:
DependencySpecification spec = new ConstructorSpecification(String.class, "foo")
.and(new ConstructorSpecification(Integer.TYPE, new Integer(42)))
.and(new SetterSpecification(String.class, "bar", "name"));
Foo bar = (Foo) new DependencyInjector().createInstance(Foo.class, spec);
(At what lengths one goes to create a simple object... :-)
Thoughts?
--knut
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]