Search code examples
javaspringtapestry

Tapestry5 use Inject service with constructor args


I'm a Tapestry5 user and wondering how I would @Inject a service class with a few arguments. From my understanding, using @Inject to inject a service class is very similar to instantiating a class with new MyClass();. The problem I seem to be having is I'm not sure how to pass the arguments into the service.

Example

Using Tapestry Servce

public class Main {

    @Inject
    private MyService myService;

    public Main() {
        //Where would I pass in my arguements?
        this.myService();

       //I can't seem to do this by passing the arg's in through 
       //this.myService(arg1, arg2) unless I may be missing something. 
    }

}

Traditional Usage

public class Main {

    public Main() {
        //In this example I can pass my arg's into the constructor. 
        MyService myService = new MyService(arg1, arg2);
    }

}

Solution

  • You are not quite right in assuming that @Inject is similar to instantiation. You might somewhat argue this when your service is annotated with @Scope(ScopeConstants.PERTHREAD) but even then, tapestries IoC will instantiate the service for you. I find that most of my services are instantiated only once by tapestry and @Inject'ing them gives me a reference to this service. If you want to @Inject a service you will first need to define it with your AppModule. The simplest way to make your service available though the IoC is to bind it like so in your AppModule:

    public static void bind(ServiceBinder binder) {
        binder.bind(ServiceInterface.class, ServiceImplementation.class)
    }
    

    Then in your pages/components you can @Inject the interface like:

    @Inject
    private ServiceInterface service;
    

    If your service then needs constructor arguments, you can create a constructor in your ServiceImplementation.class taking your required arguments. If those arguments are in themselves bound services, tapestry will figure this out and you're done. If these arguments are not services known to Tapetsry and you can't bind them for whatever reason, you can create a build method in your AppModule:

    /**
     * These methods may in them selves take bound services as arguments helping you build your new service
     */
    public ServiceInterface buildServiceInterface(AnotherBoundService service2) {
        ...
        return new ServiceImplementation(service2, someMoreArgsIfRequired)
    }
    

    Might you not want to use the IoC, you can always just instantiate the service in your page/component because they are just simple pojo's. Do have a look at the IoC documentation. It nicely outlines all powerful features at your disposal.