Trying to do the dependency injection of java generics class in Micronaut
Interface
public interface IRequestHandler<C, R> {
R handler(C c);
}
Dependency Injection
@Singleton
public record ServiceBus(IRequestHandler<C, R> iRequestHandler) implements IServiceBus{
@Override
public <C, R> R send(C c) {
return iRequestHandler.handler(c);
}
}
Interface
public interface IServiceBus {
<C,R> R send(C c);
}
Implementation
public class ProductController {
public ProductController(IServiceBus iRequestHandler){
_iserviceBus= iRequestHandler;
}
public Mono<?> get(ProductSearchCriteriaCommand searchCriteria) {
var item = _iserviceBus.<CreateProductCommand,CreateProductCommand>send(new CreateProductCommand());
return null;
}
}
Problem for me is on ServiceBus class, how can I pass the type for public record ServiceBus(IRequestHandler<C, R> iRequestHandler)
and iRequestHandler.handler(c);
@Singleton
public class CreateProductCommandHandler implements IRequestHandler<CreateProductCommand, CreateProductCommand> {
@Override
public CreateProductCommand handler(CreateProductCommand createProductCommand) {
return null;
}
}
@Singleton
public record DeleteProductCommandHandler() implements IRequestHandler<DeleteProductCommand,DeleteProductCommand> {
@Override
public DeleteProductCommand handler(DeleteProductCommand deleteProductCommand) {
return null;
}
}
When I am calling _iserviceBus.<CreateProductCommand,CreateProductCommand>send(new CreateProductCommand());
in controller I am trying to invoke handler
method in CreateProductCommandHandler
class
Similarly if I call _iserviceBus.<CreateProductCommand,CreateProductCommand>send(new DeleteProductCommand());
the handler
method of DeleteProductCommandHandler
class should get invoke
CodePudding user response:
You incorrectly defined IServiceBus interface:
public interface IServiceBus {
<C,R> R send(C c);
}
should be:
public interface IServiceBus<C,R> {
R send(C c);
}
UPD. Very basic example of registry.
public interface IRequestHandler<C, R> {
R handler(C c);
Class<C> getCmdType();
}
public class ServiceBus implements IServiceBus {
private final Map<Class<?>, IRequestHandler<?, ?>> handlerMap;
public ServiceBus(List<IRequestHandler<?, ?>> handlers) {
handlerMap = handlers.stream()
.collect(toMap(
IRequestHandler::getCmdType,
Function.identity()
));
}
@Override
public <C, R> R send(C c) {
IRequestHandler<C, R> handler = (IRequestHandler<C, R>) handlerMap.get(c.getClass());
if (handler == null) {
throw new UnsupportedOperationException("Unsupported command: " c.getClass());
}
return handler.handler(c);
}
}