The Author Online Book Forums are Moving

The Author Online Book Forums will soon redirect to Manning's liveBook and liveVideo. All book forum content will migrate to liveBook's discussion forum and all video forum content will migrate to liveVideo. Log in to liveBook or liveVideo with your Manning credentials to join the discussion!

Thank you for your engagement in the AoF over the years! We look forward to offering you a more enhanced forum experience.

jjenkov (13) [Avatar] Offline
Chapter 2 mentions string key and mention some of their problems. But the chapter seems to
ignore the advantages of string keys. The chapter also seems to forget one of the major
objectives against annotations. I'll try to explain here:

1) String Keys as Application Configuration Parameters.
String keys, when externalized into DI configuration files like
Spring XML or Butterfly Container Script (BCS), string keys have a few advantages

1) The DI config files can be used for application configuration as well
as just wiring objects together. For instance, you can define bean factories
that corresponds to configuration parameters like "noOfThreads", "noOfConnections",
"purchaseConfirmationText" etc. Rather
than having to put those config parameters in a separate property file,
and having to parse that file into object representation, the DI container
can inject those configuration parameters directly into the objects that need them.
No need for an extra application configuration mechanism. Here is a Butterfly DI Container example:

dbDriver = "org.h2.Driver";
dbUrl = "jdbc:h2:tcp://...";
dbUser = "sa";
dbPassword = "";

noOfConnections = 10;
maxIdleTime = 60000;

dataSource = com.myapp.MyDataSource(dbDriver, dbUrl, dbUser, dbPassword);

dbPool = com.myapp.ConnectionPool(dataSource, noOfConnections, maxIdleTime);

Notice how close to a standard property file the configuration of the
first 6 beans look. The only difference is the trailing semicolon (';')
on each line. Notice also how these configuration parameters are
injected directly into the components that
need them. No need to create a separate Config object or anything like that.

This is not feasible with annotations alone because you will have to recompile
the app. to make the changes in the bound beans be applied to the application.
You may even have to restart the application. Butterfly DI Container is capable
of reloading config files at runtime, meaning you don't have to shut down the
application nor recompile, to just fiddle with a configuration parameter. So,
String keys has a wider applicability than annotations in my opinion.

2) String keys vs. type safety.
Chapter 2 mentions that String keys suffers from lack of compile type checking
and therefore lack of type safety. I wrote an article arguing why type safety
is only partially lost, what you can do to at least get build time type checking,
and why this partial loss of type safety is rarely a big problem. You can find it

3) Disadvantages of annotations:
Using annotations as DI configuration mechanism has a few major disadvantages:

A) The code being wired up using DI now has the DI containers annotations
sprayed out all over it. In other words, the code actually *depends* on
the DI container!!! DI is supposed to remove dependencies, not add them.
If I wanted to change from Guice to another DI container, I would have
to run around my code and remove all those now irrelevant annotations.

B) The code being wired up should have NO KNOWLEDGE of how it is wired up in my opinion.
In other words, I don't find it acceptable to put in an annotation of @English in front
of a parameter to be injected, to signal that I want a special @English variant of the component
injected. Why not? Because, in reality you might actually need both an english and a spanish
version in the same application. Yes, you can easily change the annotations to acommodate this,
but this problems just doesn't exist when you are specifying the wiring *externally* from the
components being wired. Spring's annotation configuration mechanism is actually brilliant in
this regard, as the annotations are not added to the components being wired themselves, but to
special configuration modules! You MUST check that out! Much smarter than Guice's @Inject all
over the place in the code, where it in my opinion has no place.

C) As mentioned in the book you cannot annotate third party code for which you do not have the
source code.

D) It is not easy to specify input parameters to an injected bean via annotations. In Butterfly
BCS you can specify input parameters for a bean factory, meaning you can provide objects to
be injected into the object you are creating, and these objects to be injected can be provided
at runtime.

The fact that annotations cannot be used for application configuration, nor can be used to wire
up third party libraries, nor are easy to specify input parameter for beans factories with,
means that annotations by itself is not sufficient for fully wiring up
an application. If you need to add extra mechanisms to annotations for them to work, why have
them at all? Why not JUST have the other mechanisms? That is why I decided to opt for a full
DI DSL in Butterfly DI Container - a language that I could shape to do it all.