« Java Control Abstractions | Main | Performance Optimization in ConcurrentHashMap »

August 19, 2008

Comments

Jesse Wilson

It seems like realize could be implemented with Guice and some syntactic sugar... Perhaps something to try in Kijaro? https://kijaro.dev.java.net/

tinou

thanks for the link, I'll have a look.

Rickard Öberg

I posted some thoughts about how these issues are handled in Qi4j, which you might be interested in:
http://www.jroller.com/rickard/entry/qi4j_fixing_dependency_injection

Casper Bang

Seems to me, with the service provider build right into Java, I get 90% of the benefits of DI without having to pull it dependencies and rely on more frameworks I really want to (lord known, there are already too many on even the smallest Java project).

Tim Boudreau of NetBeans fame wrote a piece on this a few weeks ago:
http://weblogs.java.net/blog/timboudreau/archive/2008/08/simple_dependen.html

Jakob Jenkov

I am not sure I fully understand what the problem is. Is it that for each dependency you have, you also need to have it injected somewhere, to avoid GlobalApplicationContext.getBean() or Injector.getInstance() ?

Butterfly Container has a slightly different approach to this. You can have Butterfly Container adapt itself to your custom factory interface, like this:


public interface MyFactory{
Bean bean1();
Bean bean2();
Product product();
}

public class ClassThatNeedsObjects{

protected MyFactory myFactory = null;

public ClassThatNeedsObjects(MyFactory factory){
myFactory = factory;
}

public void atRunTime(){
Bean bean1 = myFactory.bean1();
Bean bean2 = myFactory.bean2();
Product product = myFactory.bean3();
}

}


The calls to the methods in the MyFactory interface are translated into beans in the container.

Notice how the atRunTime() method can actually obtain beans from the container, without ever dependending on the container's interface. It only knows the MyFactory interface, which is something
you write yourself.


The configuration of the container would look like this:


bean1 = * com.blabla.Bean("value1");
bean2 = * com.blabla.Bean("value2");
product = * com.blabla.Product();

classThatNeedsObjects = * com.blabla.ClassThatNeedsObjects(#product);


Bob Lee

My thought was that we could reuse "import" instead of "realize" so we don't have to add a new keyword.

MartinJ

Interesting idea! Never really thought about something like that. But there's one thing I don't get: How would the language know which concrete implementation of MovieFinder to "realize"?

fletch

Meh,

DI is great. Doing it in a configuration step e.g. through XML, annotations or a scripting language is not a property of DI, it's an implementation. In my book, this still qualifies as DI:

MyService myService = new MyService();
MyController myController = new MyController();
myController.setService(myService);

Bob Lee

@MartinJ: One idea: it could work like/with class loaders. i.e., you'd have a thread local "object loader".

@fletch: I agree. I actually present the "DI by hand" approach in the beginning of my talk, and then I go into why you'd want to use a framework: http://crazybob.org/2007/06/introduction-to-guice-video-redux.html

tinou

@casper: I'm not too familiar with SPI, but it sounds like a service locator approach, and seems heavyweight since it requires jars (is that correct?)

@MartinJ: i'll echo bob's thoughts. my first thought is some type of classloading/classpath approach, with override. the one nice thing about classloading/classpath is it'll force better module/component dependencies. for example

client-module: client code
service-interface-module: defines interfaces to your services
implementation-module: defines concrete implementation
mock/test-module: defines the mock/test implementations

if your modules aren't deployed correctly then you'll get ambiguous realizations/imports errors.

echo'ing gilad's thoughts, i wished java packages could be used for dependency management. right now packages fairly limited.

MartinJ

bit late but anyways...

@Bob & tinou: I'm still a bit unsure as to how that could work exactly. If I understand you correctly the "realized/imported" concrete implementation is known because it's part of some JAR on the classpath, right? So one would just swap in some other JAR-File to get a different implementation. What if you've got more than one implementation? Care to explain your ideas a bit more? I think it's a really interesting idea for the lanugage to provide such a mechanism...

Reedo

Off-hand, I wonder how far someone could get just with properties files to specify implementations, like the way the security.provider class is set in java.security (with which I became way too familiar when I was writing code to run on Websphere).

Then a unit test, for instance, could override this implementation property in code.

The comments to this entry are closed.