<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Supple software comments on Dependency Injection Without Frameworks</title>
    <link>http://www.supplesoftware.com/</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>Supple software comments</description>
    <item>
      <title>"Dependency Injection Without Frameworks" by petrovg</title>
      <description>&lt;p&gt;I had to do this really small app recently. I wanted to use dependency injection, which I have come to really like now, but it seemed absolutely ridiculous to dump the spring jar and the few megs of dependencies in a project that only consisted of 20-odd classes.&lt;/p&gt;

&lt;p&gt;So I decided to roll my own.&lt;/p&gt;

&lt;h3&gt;Initial thoughts&lt;/h3&gt;

&lt;p&gt;The main thing is - I want the classes to be unconcerned about their collaborators - they just declare a property of some interface type with getters and setters, and leave somebody else to assemble the whole thing. Thus, in the spirit of DI, you achieve very loose coupling between the objects, which simplifies the design and improves testability.&lt;/p&gt;

&lt;p&gt;So, I need to design and write my classes as if for a framework - they would only depend on interfaces and not bother with the implementation. I decided to use setter injection. The only problem was: How do I assemble the whole thing? Looking at Spring again, I decided to have one servlet, which accepts all the requests and delegates their handling to request handlers. On initialisation,the servlet would build the whole application. True to the single responsibility principle, though the servlet would not do this itself - I decided to have an ApplicationAssembler interface and implementation, which would be responsible for the wiring of the components.&lt;/p&gt;

&lt;p&gt;It was obvious, that the ApplicationAssembler would be the equivalent of Spring&amp;#8217;s XML wiring declarations, except for simplicity, my  implementation would just build them using Java. Note that this means there&amp;#8217;s a compile-time dependency between ApplicationAssembler and just about everything, but I can live with this just fine, because it&amp;#8217;s logically correct, and the individual classes are still very loosely coupled. If I wanted to remove the compile-time dependency, I could always make some XML or Groovy based application assembler.&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s a more specific scenario - The servlet has a map of requestHandlers, mapped against their urls. When it loads (init method), it makes an ApplicationAssembler and asks it to populate all the handlers with fully injected collaborators. From then on it&amp;#8217;s easy - once a request arrives, the application looks up the fully populated handler and asks it to do the job. Some sort of abstract handler could provide the recipe for the common bits (validate, do business, redirect), and concrete handlers could implement the details if relevant.&lt;/p&gt;

&lt;p&gt;At this point I got a bit worried - am I going to do more work than if I had just used Spring? Hm&amp;#8230;. we&amp;#8217;ll see. Also, it seemed a bit odd, that all I had in my whole application (at the top level) are request handlers. Is really everything in a simple web app a request handler? Or does this approach hide the rest&amp;#8230; Hm&amp;#8230; As I said, we&amp;#8217;ll see.&lt;/p&gt;

&lt;h3&gt;Design&lt;/h3&gt;

&lt;p&gt;I sketched a small picture, and it did look quite neat - Mostly the fact that the dependencies were quite minimal. The ApplicationController (that&amp;#8217;s how I named the servlet - I know - somewhat unimaginative) depended only on the ApplicationAssembler interface and the abstract RequestHandler. This really is the whole thing:&lt;/p&gt;

&lt;p&gt;&lt;img src="/images/diwf/diwf1.jpg" /&gt;&lt;/p&gt;

&lt;p&gt;I have two request handlers in this example, RegisterUserRequestHandler and ShowUserHoldingsRequestHandlers. The two business objects are DataStore - to save the new registration and Mailer - to send the reg confirmation.&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s one request handler:&lt;/p&gt;

&lt;pre class="codeSample"&gt;
public class RegisterUserRequestHandler extends BaseRequestHandlerAdaptor {

    // Collaborators
    private Mailer mailer;
    private DataStore dataStore;

    public void setDataStore(DataStore dataStore) {
        this.dataStore = dataStore;
    }

    public void setMailer(Mailer mailer) {
        this.mailer = mailer;
    }

    public void handleRequest(HttpServletRequest request,
            HttpServletResponse response) 
        throws IOException, ServletException {

        ....
        dataStore.insertUser(userData);
        mailer.sendConfirmation(userId);
        .....
    }
}
&lt;/pre&gt;

&lt;p&gt;I&amp;#8217;ve removed the details, but the main concept is shown well - it declares the mailer and dataStore as interfaces, and setters for them, and that&amp;#8217;s it. It&amp;#8217;s down to the assembler to set the actual instances. Not only is this simple, but when writing testing this class, it&amp;#8217;s easy to just set some mocks instead of the real implementations.&lt;/p&gt;

&lt;p&gt;I will write the application assembler to wire it all together as shown on this diagrams for RegisterUserRequestHandler:&lt;/p&gt;

&lt;p&gt;&lt;img src="/images/diwf/diwf2.jpg" /&gt;&lt;/p&gt;

&lt;p&gt;and ShowUserHoldingsRequestHandler:&lt;/p&gt;

&lt;p&gt;&lt;img src="/images/diwf/diwf3.jpg" /&gt;&lt;/p&gt;

&lt;p&gt;The code that wires it all together is actually quite simple:&lt;/p&gt;

&lt;pre class="codeSample"&gt;
...
public class SimpleApplicationAssembler implements ApplicationAssembler {

    public Map&lt;String, RequestHandler&gt; buildRequestHandlers() {

        // Make the map for the request handlers
        Map&lt;String, RequestHandler&gt; requestHandlers = new HashMap&lt;String, RequestHandler&gt;();

        // Make a mailer
        SimpleMailer simpleMailer = new SimpleMailer();
        simpleMailer.setSmtpServerUrl("mail.supplesoftware.com");

        // Get a datasource
        DataSource dataSource = null;
        try {
            dataSource = (DataSource) (new InitialContext()).lookup("jdbc/MyDataSource");
        } catch (NamingException e) {
            throw new RuntimeException("Datasource jdbc/MyDataSource not found");
        }

        // Make a data store
        SimpleDataStore simpleDataStore = new SimpleDataStore();
        simpleDataStore.setDataSource(dataSource);

        // Make the request handlers
        RegisterUserRequestHandler registerUserRequestHandler = new RegisterUserRequestHandler();
        registerUserRequestHandler.setDataStore(simpleDataStore);
        registerUserRequestHandler.setErrorView("/regform.jsp");
        registerUserRequestHandler.setSuccessView("/registered.jsp");
        registerUserRequestHandler.setFormView("/regform.jsp");
        registerUserRequestHandler.setMailer(simpleMailer);
        requestHandlers.put("/register.shtml", registerUserRequestHandler);

        ShowUserHoldingsRequestHandler showUserHoldingsRequestHandler = new ShowUserHoldingsRequestHandler();
        showUserHoldingsRequestHandler.setErrorView("/error.jsp");
        showUserHoldingsRequestHandler.setSuccessView("/showfunds.jsp");
        showUserHoldingsRequestHandler.setDataStore(simpleDataStore);
        requestHandlers.put("/showholdings.shtml", showUserHoldingsRequestHandler);

        return requestHandlers;
    }
}
&lt;/pre&gt;

&lt;p&gt;And this is the controller that uses it all:&lt;/p&gt;

&lt;pre class="codeSample"&gt;
...
/**
 * Dynamic request handler for the DIWF example
 */
public class ApplicationController extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {

    /**
     * RequestHandlers mapped on url
     */
    Map&lt;String,RequestHandler&gt; requestHandlers; 

    /**
     * Uses the ApplicationAssembler defined in the applicationAssembler 
     * parameter to populate the requestHandler map
     */
    @Override
    public void init() throws ServletException {
        String applicationAssemblerName = getInitParameter("applicationAssembler");
        ApplicationAssembler applicationAssembler;
        try {
            applicationAssembler = 
                (ApplicationAssembler) Class.forName(applicationAssemblerName).newInstance();
        } catch (InstantiationException e) {
            throw new ServletException("Can not make an ApplicationAssembler", e);
        } catch (IllegalAccessException e) {
            throw new ServletException("Can not make an ApplicationAssembler", e);
        } catch (ClassNotFoundException e) {
            throw new ServletException("Can not make an ApplicationAssembler", e);
        }
        assert applicationAssembler != null;
        requestHandlers = applicationAssembler.buildRequestHandlers();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        service(request, response);
    }   

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        service(request, response);
    }

    /**
     * Looks up the request handler by the request url and delegates to it
     */
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        RequestHandler requestHandler = requestHandlers.get(request.getServletPath());
        if (requestHandler != null) {
            requestHandler.handleRequest(request, response);
        }
        else {
            System.out.println("Request path " + request.getServletPath() + " not mapped");
            response.sendError(404);
        }
    }
}
&lt;/pre&gt;

&lt;p&gt;I noticed that some of the functionality is common between request handlers, so put a base abstract class between the interface and the concrete classes to implement it, like this:&lt;/p&gt;

&lt;p&gt;&lt;img src="/images/diwf/diwf4.jpg" /&gt;&lt;/p&gt;

&lt;p&gt;From here you can go as simple or complex as needed. Even in this simplest of all examples, there&amp;#8217;s some repetition, which can be easily refactored using the Recipe pattern, eg. The error messages must go in a resource bundle. Some of the request handlers functionality can be abstracted. The validation can be handled by predefined validators. The views can be rendered into XML and transformed using XSL. The definition of the app structure can be XML-ised instead of hard-coded, and so on, until it starts looking like you&amp;#8217;re building your own DI framework.&lt;/p&gt;

&lt;p&gt;At which point it&amp;#8217;s probably wise to switch to an existing one.&lt;/p&gt;

&lt;h3&gt;Afterthoughts&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;I could have used a groovy script to do the wiring (ApplicationAssembler). That would mean I could change some implementations without recompiling. Don&amp;#8217;t think that would happen in reality, though.&lt;/li&gt;
&lt;li&gt;There&amp;#8217;s a clear distinction here between two main sorts of objects - the main players - request handlers and business logic objects, which are durable and stay there for the life of the app and the bits that you just pass around and dispose of, such as Price, or UserFeedbackForm. The main players are built by the ApplicationAssembler and there are limited number of instances of them. The disposable ones are made on the fly. It&amp;#8217;s allright for an object to make one of them, because it is not in any form of compositional or aggregational relationship with it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Advantages over using a framework&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;It&amp;#8217;s simple&lt;/li&gt;
&lt;li&gt;The wiring is strongly typed. Compare to XML.&lt;/li&gt;
&lt;li&gt;It&amp;#8217;s easy to sell. In some companies, the mention of Spring or Pico will earn you nothing but pain. This allows you to do DI without irritating the elderly. Because the objects are still written the DI way, it&amp;#8217;s easy to migrate to a framework later.&lt;/li&gt;
&lt;li&gt;This approach is much simpler than using a framework, but at the same time the whole mechanism is exposed for all to see and understand. The less experienced developers do not face some incomprehensible thing that works as if by magic, and actually have some chance of understanding the actual meaning of DI and IOC.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Disadvantages&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;When the app starts getting big, the ApplicationAssembler will get messy. Although in the tiny example I provide here, it&amp;#8217;s still quite neat. I suppose it could be split into parts, but a framework has all these considerations sorted already.&lt;/li&gt;
&lt;li&gt;The frameworks offer various strategies for instantiating objects (beans). Here it&amp;#8217;s done once, so all your objects will be, for all intents and purposes, Sin*&amp;amp;%#ons. Or Moretons. But you can&amp;#8217;t get it to create a new one every time, or maintain a pool, at least not easily. You&amp;#8217;d have to give factories to your objects, instead of other objects, which in some ways defies the point.&lt;/li&gt;
&lt;li&gt;The previous point raises questions about concurrency - I&amp;#8217;m not going to think about this now, because it&amp;#8217;s out of scope, but clearly, state should be avoided and as the app grows you&amp;#8217;ll have to think about pooling and stuff.&lt;/li&gt;
&lt;li&gt;Some frameworks, notably Spring actually give you a lot more than just dependency injection, including, transaction management, aop, etc. goodies, you&amp;#8217;ll have to go a long way to write these yourself.&lt;/li&gt;
&lt;/ul&gt;</description>
      <pubDate>Sun, 16 Apr 2006 07:00:00 PDT</pubDate>
      <guid>&lt;a href="/articles/2006/04/16/dependency-injection-without-frameworks"&gt;Dependency Injection Without Frameworks&lt;/a&gt;</guid>
      <link>&lt;a href="/articles/2006/04/16/dependency-injection-without-frameworks"&gt;Dependency Injection Without Frameworks&lt;/a&gt;</link>
    </item>
  </channel>
</rss>
