Rece
Rece

Reputation: 67

Spring IOC DI with runtime parameters

I'm relativity new to IOC and DI, so I'm guessing that I am missing some high-level design principle here, but I cannot figure out how to get my architecture working.

I have a REST API endpoint that accepts two pieces of POST data: customer ID, and Type ID. The rest api then needs to return a set of data for that specific customer/type combo.

Here is a crude picture of what I am doing: enter image description here

The controller is taking the entity IDs passed in via post data, and via a JPA repository getting the appropriate Entities for them.

I then construct a data generator object (that takes the entities as constructor parameters), and use that to handle all of the data gathering for the API.

The Problem: because the Data Generator takes the two dynamic constructor parameters, it cannot be DI'ed into the Controller, but instead must be made with new. Inside of the Data Generator, however, I need access to JPA repositories. The only way to get access to these repositories is via DI. I cannot DI however, as the object was new'ed not DI'ed by the IOC container.

Is there a way to architect this so that I don't have this problem? Am I breaking some rule regarding IOC? Do I have wrong assumptions somewhere? Any advice is appreciated.

Thanks!

Edit: Pseudo code for Data Generator

public class DataGenerator {
    private Customer customer;
    private Type type

    public DataGenerator(Customer customer, Type type) {
        this.cusomter = customer;
        this.type = type;
    }

    public generateData() {
        if(customer == x && type == y) {
            //JPA REPOSITORY QUERY
        } else {
            //DIFFERENT JPA REPOSITORY QUERY
        }
    }
}

Upvotes: 0

Views: 357

Answers (1)

DominicEU
DominicEU

Reputation: 3631

I think you may have gotten confused somewhere along the line. You should have a Service that hits your repositories, and provide the information to the controller. One crude setup would be something like this.

@Controller 
public MyController {

    @AutoWired
    private DataService dataService;

    @RequestMapping(value = "/", method = RequestMethod.GET)
    private DataGenerator readBookmark(@PathVariable Long customerId, @PathVariable Integer typeId) {
        return dataService.getData(customerId, typeId);
    }
}

@Service
public class DataService {

    @AutoWired
    private JPARepository repository;

    public DataGenerator getData(long customerId, int typeId) {
        Type typeDetails = repository.getType(typeId);
        Customer customerDetails = repository.getCustomer(customerId);
        return new DataGenerator(customerDetails, typeDetails);
    }
}

Upvotes: 1

Related Questions