I have a play application and want to take a common operation out from the application and make it as a library in order to use in other play applications.

This proposing library has a contract(interface) and several implementations of top of that. I have 2 questions;

  1. What if I use guice to bind contact and implementations with named injection(using annotations) and call them with the appropriate annotation in the play application without instantiating library classes in the apply application?

  2. Can we use such libraries in other java applications without any issue? Ex: Use a library which used Guice in a Spring application


You are confusing dependency injection (DI) with the more specific idea of using a DI framework to supply those injected dependencies. remember that it's perfectly possible to use pure DI to inject dependencies without a framework. So the answer to the question, "Is it good to use dependency injection in a java library?", is "yes". As a default state, you should use DI everywhere, only not using it when there's a compelling reason not to.

But the body of your question then asks about tying your library to a specific DI framework. Unless you are sure that all of your users will be using that framework, then that is likely a bad idea. You couple people to a specific framework that they may not wish to use. Further, they may already be using another framework and they tend not to be compatible with each other. As a result, you risk driving folk away from your library as it's too difficult to use.

So the answer to the question, "should I couple my library to guice (or another framework)" is likely to be "no" for most scenarios.


Q: Is it good to use dependency injection in a java library?

This is totally up to you. However, imposing a specific framework or tool to make the library to work could dissuade developers from adopting the library. Those concerned by design best practices could argue that such a library is locking the application to a specific transitive dependency. In this case, Guice.

Transitive dependencies are not dependencies of our application. These are implementation details of those libraries we directly depend on. Ideally, we don't want to couple our application to the implementation details of 3rd party libs.

Adopting a new library should be possible without explicitly accessing or using its implementation details. Instead, it should provide us with abstractions that keep its "details" away from us. If you could hide Guice from the consumer then it's ok. But if you force the consumer to know about Guice (and use its elements explicitly) then I would suggest dropping Guice in favour of a cleaner design so developers can choose the DI implementation they want. By "cleaner design" I mean declaring constructors and setters to inject dependencies and do a proper use of the accessor modifiers.

Summarising, it's strongly advisable to keep the implementation details of our libraries away from the consumers. In your case, provide an abstraction simple to reason about but don't go beyond the library responsibility. Leave some gaps unfilled so consumers can fill them up with the glue of their choice. Even if you are the only consumer, at some point you might decide to move from Guice to Spring or vice-versa. Or, why not, to stop using both and go back to the healthy practice of instantiating dependencies yourself.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.