While the essence of Inversion-of-Control (IoC) container appears to be easily comprehensible and well understood, as pointed out in the IoC containers other than the DI pattern
, it is subtly confusable and badly misread. One of the biggest confusing is about the use of XML. Namely, application composite wiring/configurations are programmed as XML documents (or textual strings). This practice in IoC containers, notoriously known as the "XML Hell"
, draws various FUD criticisms, such as:
* These XML codes are merely lousy and verbose procedural scripts.
* These XML codes are poorly debuggable.
* These XML codes lack static type safety.
* These XML codes are refactoring-adverse.
Here, in this article, these seemingly evident FUD criticisms are questioned:
Are these XML codes verbose and lousy procedural scripts?
First of all, these XML codes are not scripts that verbalize
the procedures to produce the required configurations. Instead, they are models that visualize
the required composite layout themselves (or requirements and constraints). This is just like the distinction between the assembly instruction book of a vehicle and its design blueprint. Hence, these XML codes are meant to be schematically intuitive and self-documenting rather than linguistically fluent and concise
Secondly, these XML codes are intended to serve as mediating data worksheets
as well. These data worksheets are going to be exchanged between IoC containers and completely decoupled applications/plugins that provide value-added features, such as model generation, editing, displaying, transformation, verification, storing, and querying. Therefore, these XML codes are preferred to be programmatically manipulable as first class objects to heterogeneous programs rather than grammatically readable as natural language sentences to English programmers.
It is widely thought that such a data modeling issue was no more than another nail for the universally effective golden hammer - procedural languages (such as Java). A chief scientist of a Java consulting firm once even made an assertion: "Everything that can be done with xml should be doable from a java program".
Consequently, various kludges have been invented and enthusiastically practiced to eliminate XML for data modeling, for instance, by expressing data composite model layouts in procedural method chaining layouts (i.e. the so-called fluent API coding style) or Java annotated data type layouts (i.e. metadata). Although claimed as substitutes or killers of their XML counterpart, it is not hard to see that these clever kludges are merely poorman's mimics of declarative data description languages. Not only they lack language level support of formal and intuitive schema definitions and structure/content integrity constraints, but also their codes are hard to be manipulated as first class objects. These "using procedural language for data modeling"
kludges appear to have certain claimed advantages (such as debuggable, static type safety, refactoring-friendly) over XML, they missed the fundamental points of both the procedural programming and the data modeling paradigms in general.
Are these XML codes poorly debuggable?
Here, the "debug" specifically means stepping and tracing through the runtime executions of procedure codes at source level. When comparing to IoC containers, XML-eliminated DI frameworks frequently emphasize their advantage (as a killer feature) of being able to debug user authored application assembling/configuring codes written in procedural languages. Nevertheless, relying on such stepping/tracing debug simply indicates the following two facts of these DI wiring programs and their languages:
* these programs consist user designed procedural code and user defined mutable states/variables.
* these programs are written in languages that lack of statically verifiable data schema support
On the contrary, user authored XML codes in IoC containers are not procedural scripts but data descriptions that model the required composite arrangements with well defined schemata and statically verifiable integrity constraints. In general, code orders in these XML programs do not imply the actual step-by-step imperative execution orders of the underlying plumbing operations performed transparently by IoC containers. Hence, just like freeing from runtime debugging syntax errors, static type errors, and memory pointer arithmetic faults is an advantage of the Java environment, relieving the burden of runtime debugging structure/content constraint violations and IoC plumbing procedures is the very point and the strength of IoC containers and the data description language like XML!
Are these XML codes unable to feature static type safety?
This FUD critism is specific to the static type safety. This is because that the dynamic type safety is already supported in IoC containers through comparing reflection retrieved metadata informations against operation signatures referred in these XML codes. For static type safety, component type informations are supposed to be retrieved from POJO (and/or POCO) component source code. Apparently, this was considered by this FUD to be not possible or significantly difficult.
However, firstly, it is obvious that what should be blamed here is not these XML codes but those POJO/POCO source codes written in classic procedural languages. Namely, the difficulty (if any) is not on inspecting operation signatures referred in these XML code but on retrieving type informations from those POJO/POCO source code. In another word, this issue actually reveals an advantage of these XML codes over classic procedural language code on being explicitly manipulable as first class objects.
Secondly, various "static reflection" engines for these procedural languages, such as Eclipse CDT C++ DOM/AST, JDT Java DOM/AST (since June 2004, Eclipse 3.0), GCC-XML (since 2002), Eclipse JDT JDOM (as early as 2002, for Eclipse 1.x/2.x) have long and widely been available. With these engines, type information "static reflection" from POCO/POJO component source code is as simple as dynamic reflection from compiled metadata. Therefore, static type safety check for these XML codes is as easy as the widely supported dynamic type safety for IoC containers.
Thirdly, this FUD criticism itself is merely a red herring to mislead readers to believe that, without static type safety, these XML codes would imply significant overhead (claimed to be 10 times slower) and be error prone at runtime. Nevertheless, in IoC containers, dynamic type check on each signature in these XML codes needs only be performed once (or very few times). Hence, the real performance overhead from dynamic type check is negligible for almost all real world applications that use decent IoC containers. More importantly, in IoC/DI scenario, operation signatures referred in these XML codes are resolved (and checked) by IoC container at applications (especially test applications) initialization or reinitialization phase. Hence, these XML codes are no longer involved in the executions of the applications once they passed this initialization/reinitialization phase, let along to cause runtime type errors in production applications. Certainly, a start-up time type check that requiring a start-up test is still different from source code editing or compiling time check. However, arguing such a start-up type check was practically unacceptable would be self-contradictory to the previous argument that emphasized the advantage of runtime debuggability which implies more than starting the applications.
Fourthly, with regarding to static code check, this FUD criticism inadvertently brought up a fundamental weakness of procedural languages and a significant strength of the XML paradigm. Namely, grammar (or syntax structure) and static type safety check of procedural languages tend to be too primitive and too generic to ensure user authored procedures are free from runtime errors or wrong runtime results without errors. This is why procedural languages and their XML-eliminated DI frameworks emphasize runtime debug and sufficient runtime test coverage. On the contrary, in IoC containers, these XML codes do not specify the runtime procedures but explicitly describe the required results and, therefore, are not only inherently free from runtime errors caused by procedural bugs in user codes but also enable much sophisticated and problem/domain specific schema verifications to statically diagnose errors in user described requirements or even results themselves.
Are these XML codes refactoring-adverse?
This FUD claim can be put as: POCO/POJO function signatures are expressed as literal strings in these XML codes. Because literal string in C++/Java code do not participate in code refactoring, hence, these XML code are not able to participate in component interface refactorings either. The erroneousness of this FUD claim is fail to understand that having a pair of quote characters surround a string text is merely an appearance rather than the cause of "refactoring-adverseness". In fact, the quote character pairs surrounding string texts are removed at lexical analysis stage even before these strings being added to the abstract syntax trees (AST) internally used by compilers or refactoring engines. The "refactoring-adverseness" of these strings is not due to the quote character pairs surrounding them but simply because the literals strings themselves in C++ or Java languages have no language level connections to names/signatures of variables, interfaces/classes, and/or functions/methods known by refactoring engines.
On the contrary, the mapping from the attribute values in form of quoted strings in these XML codes to POCO/POJO interface/class type names and function/method signatures are well defined. Otherwise, the underlying IoC engines would not even be able to resolve invocation methods through reflection in the first place. Hence, having refactoring on these XML codes is straightforward, and having them participate in POCO/POJO component code refactoring is not more difficult than (if not significantly easier than) the original work of supporting refactoring on C++/Java code themselves (would C++/Java be criticized as being refactoring-adverse as well?), not to mention this integration approach has largely been simplified by the open architectures of existing refactoring IDEs (such as the Eclipse Language Toolkit (LTK) refactoring architecture) and the Eclipse CDT C++ DOM/AST and JDT Java DOM/AST "static reflection" engines.
Furthermore, the "refactoring" in this FUD criticism obviously meant the interactive refactorings supported by integrated development environments (IDEs) of procedural languages, such as Eclipse. Having these XML code participate in such an interactive refactoring of POCO/POJO, as pointed out above, can be supported in Eclipse. However, it would only make sense if the XML code and the POCO/POJO component/service implementation codes were developed together within the same IDE project. Unlike programmatic API frameworks (as well as those XML-eliminated DI frameworks) which consider wiring configurations an statically built-in integral part developed together with and spread throughout their applications, IoC containers have assembly/deployment arrangement code completely separated from POCO/POJO component/service implementations. Namely, these arrangement code tend to be authored independently outside of (or decoupled from) the development phase(s)/cycle(s), IDE project(s), and/or brain(s)/team(s)/vendor(s) of those components/services. Hence, having these XML code participate in an interactive refactoring of those POCO/POJO code is largely a phantom requirement from misreading or misusing of IoC containers.