Mentawai Web Framework

Inversion of Control

Mentawai implements a very simple and efficient IoC Container, but not less powerful than the other ones out there. Through the org.mentawai.filter.IoCFilter global filter, you can instantiate and inject any component inside your actions and/or beans (POJOs). Below we have a component called Talker that was implemented in three different ways: PortugueseTalker, UnpoliteTalker and PoliteTalker.


public interface Talker {
    
    public String saySomething();
    
}

public class PortugueseTalker implements Talker {
        

    public String saySomething() {
        
        return "from PortugueseTalker: Como está vc?";              
    
    }
        
        
}

public class UnpoliteTalker implements Talker {
    
    private String name;
    
    public UnpoliteTalker(String name) {
        this.name = name;
    }
    
    public String saySomething() {
        return "from " + name + " (" + toString() + "): Hello you #$#((%$#!";
    }
    
}

public class PoliteTalker implements Talker {
    
    private String name;
    
    public void setName(String name) {
        this.name = name;
    }
    
    public String saySomething() {
        return "from " + name + " (" + toString() + "): Hello Sir!";
    }
    
}

Now lets analyse how we can configure these components inside our ApplicationManager.java:


public class ApplicationManager extends org.mentawai.core.ApplicationManager {
    
    public void init() {
        
        // Define the IoC components...
        
        ioc("talker1", PortugueseTalker.class);
        
        ioc("talker2", PoliteTalker.class)
            .addProperty("name", "Polite guy");
            
        ioc("talker3", UnpoliteTalker.class, SESSION)
            .addInitValue("Unpolite guy");
            
    }
    
    public void loadActions() {
        
        
        // IoC Global Filter...
        filter(new IoCFilter());
        
        // Injection filter to inject values straight into the action
        filter(new InjectionFilter());
    
        action("/HelloIoC", HelloIoC.class)
            .on(SUCCESS, fwd("/show.jsp"));
    }
}

The talker1, talker2 and talker3 components will be injected straight into the action through a setter method (Ex: setTalker1(Talker t)) or straight into a public or private field (Ex: Talker talker1). The InjectionFilter is actually the filter which is controlling and executing this injection. However you should note that you can also use the IoCFilter without the InjectionFilter, the only difference being that you will access your components through the action input because they will not be injected automatically by the InjectionFilter.


public class HelloIoC extends BaseAction {
    
    private Talker talker1 = null;
    private Talker talker2 = null;
    private Talker talker3 = null;
    
    public void setTalker1(Talker t) {
        this.talker1 = t;
    }
    
    public void setTalker2(Talker t) {
        this.talker2 = t;
    }
    
    // t3 will be injected straight into the private field... (no need for setter)
    
    public String execute() throws Exception {
        String s1 = null;
        String s2 = null;
        String s3 = null;
        
        if (talker1 != null) {
            s1 = talker1.saySomething();
            output.setValue("from_t1", s1);
        }
        if (talker2 != null) {
            s2 = talker2.saySomething();
            output.setValue("from_t2", s2);
        }
        if (talker3 != null) {
            s3 = talker3.saySomething();
            output.setValue("from_t3", s3);
        }
        return SUCCESS;
    }
}

If we decide not to use a InjectionFilter, our action would be like that:


public class HelloIoC extends BaseAction {

    public String execute() throws Exception {
        
        Talker talker1 = (Talker) input.getValue("talker1");
        Talker talker2 = (Talker) input.getValue("talker2");
        Talker talker3 = (Talker) input.getValue("talker3");
        
        String s1 = null;
        String s2 = null;
        String s3 = null;
        
        if (talker1 != null) {
            s1 = talker1.saySomething();
            output.setValue("from_t1", s1);
        }
        if (talker2 != null) {
            s2 = talker2.saySomething();
            output.setValue("from_t2", s2);
        }
        if (talker3 != null) {
            s3 = talker3.saySomething();
            output.setValue("from_t3", s3);
        }
        return SUCCESS;
    }
}

To conclude, the Mentawai IoC configuration is very small and everything happens automatically and transparently. The main characteristics of a Mentawai IoC component are:

  • Your components can have three different scopes: REQUEST, SESSION or APPLICATION.

  • Your components can have configurable properties, that you can set through the addProperty() method.

  • Your components can have constructors that take parameters, that you can set through the addInitValue() method.

  • There is no need for interfaces (enablers). The injection is done by the InjectionFilter and can be through a setter or field (private or public).

You may click here to download an IoC example.