class DefaultDimensionManager implements DimensionManager {

    private final List<DimensionProvider> dimensionProviders = new CopyOnWriteArrayList<>();
    private final List<DimensionUserBindProvider> bindProviders = new CopyOnWriteArrayList<>();

    private final Mono<Map<String, DimensionProvider>> providerMapping = Flux
            .defer(() -> Flux.fromIterable(dimensionProviders))
            .flatMap(provider -> provider
                    .getAllType()
                    .map(type -> Tuples.of(type.getId(), provider)))
            .collectMap(Tuple2::getT1, Tuple2::getT2);

    public DefaultDimensionManager() {

    }

    public void addProvider(DimensionProvider provider) {
        dimensionProviders.add(provider);
    }

    public void addBindProvider(DimensionUserBindProvider bindProvider) {
        bindProviders.add(bindProvider);
    }

    private Mono<Map<String, DimensionProvider>> providerMapping() {
        return providerMapping;
    }

    @Override
    public Flux<DimensionUserDetail> getUserDimension(Collection<String> userId) {<FILL_FUNCTION_BODY>}
}

        return this
                .providerMapping()
                .flatMapMany(providerMapping -> Flux
                        .fromIterable(bindProviders)
                        //获取绑定信息
                        .flatMap(provider -> provider.getDimensionBindInfo(userId))
                        .groupBy(DimensionUserBind::getDimensionType)
                        .flatMap(group -> {
                            String type = group.key();
                            Flux<DimensionUserBind> binds = group.cache();
                            DimensionProvider provider = providerMapping.get(type);
                            if (null == provider) {
                                return Mono.empty();
                            }
                            //获取维度信息
                            return binds
                                    .map(DimensionUserBind::getDimensionId)
                                    .collect(Collectors.toSet())
                                    .flatMapMany(idList -> provider.getDimensionsById(SimpleDimensionType.of(type), idList))
                                    .collectMap(Dimension::getId, Function.identity())
                                    .flatMapMany(mapping -> binds
                                            .groupBy(DimensionUserBind::getUserId)
                                            .flatMap(userGroup -> Mono
                                                    .zip(
                                                            Mono.just(userGroup.key()),
                                                            userGroup
                                                                    .<Dimension>handle((bind, sink) -> {
                                                                        Dimension dimension = mapping.get(bind.getDimensionId());
                                                                        if (dimension != null) {
                                                                            sink.next(dimension);
                                                                        }
                                                                    })
                                                                    .collectList(),
                                                            DimensionUserDetail::of
                                                    ))
                                    );
                        })
                        )
                .groupBy(DimensionUserDetail::getUserId)
                .flatMap(group->group.reduce(DimensionUserDetail::merge));
    
<no_super_class>