It would help to know a little more about the process. How many I/O are involved? What type of operation is this? Discrete assembly machine? Continuous process heavy on analog?
In general, I would think that your control program would not have any real I/O but use internal registers for them.
Then in a separate file (two of them) you would assign the inputs to the internal registers (one of the first program calls), and as the last routine you would assign the output registers to the real world addresses.
This is a common practice, but for your dynamic application, you may used indirect address for the actual I/O, and have the indexes set up as variables from the HMI:
It could be complicated depending on how wide ranging the I/O count is and what type of controller. If you need to be able to assign an output to any point among slots 2,3,9, 12, or remote rack 7 slots 3 or 4, that could be hairy.
If the choice is limited to a single chassis slot, then it could be pretty simple.