@Override
    public void validateContext() throws ExtensionException {
        List<Class<?>> allExtensionList = new ArrayList<>();

        for (IBusiness<T> business : businessManager.listAllBusinesses()) {
            if (business.usedAbilities() == null) {
                continue;
            }

            allExtensionList.addAll(business.implementsExtensions());

            Set<String> codeSet = new HashSet<>();
            Set<Integer> prioritySet = new HashSet<>();

            codeSet.add(business.code());
            prioritySet.add(business.priority());

            for (UsedAbility usedAbility : business.usedAbilities()) {
                IAbility<T> ability = abilityManager.getAbility(usedAbility.code());
                allExtensionList.addAll(ability.implementsExtensions());

                if (codeSet.contains(usedAbility.code())) {
                    throw new ExtensionException("business " + business.code() + " used ability code " + usedAbility.code() + " duplicate");
                }

                if (prioritySet.contains(usedAbility.priority())) {
                    throw new ExtensionException("business " + business.code() + " used ability priority " + usedAbility.priority() + " duplicate");
                }

                codeSet.add(usedAbility.code());
                prioritySet.add(usedAbility.priority());
            }
        }

        if (!allExtensionList.isEmpty()) {
            IAbility<T> defaultAbility = abilityManager.getAbility(BaseDefaultAbility.DEFAULT_CODE);
            List<String> notImplemented = new ArrayList<>();
            for (Class<?> clazz : allExtensionList) {
                if (!clazz.isAssignableFrom(defaultAbility.getClass())) {
                    notImplemented.add(clazz.getName());
                }
            }
            if (!notImplemented.isEmpty()) {
                throw new ExtensionException("default ability should implements all extension interface, but current default ability not implements extension " + Arrays.toString(notImplemented.stream().distinct().toArray()));
            }
        }
    }
@Test
    public void testValidateContext() throws Exception {
        ExtensionException e;
        DefaultExtContext<Object> context = new DefaultExtContext<>(false, false);
        context.validateContext();

        context.registerBusiness(new BusinessUnknownAbilityCode());
        e = assertThrows(ExtensionException.class, context::validateContext);
        assertEquals("ability Unknown not found", e.getMessage());

        context = new DefaultExtContext<>(false, false);
        context.registerAbility(new AbilityM());
        context.registerBusiness(new BusinessUsedAbilityCodeDuplicate());
        e = assertThrows(ExtensionException.class, context::validateContext);
        assertEquals("business BusinessUsedAbilityCodeDuplicate used ability code AbilityM duplicate", e.getMessage());

        context = new DefaultExtContext<>(false, false);
        context.registerAbility(new AbilityM());
        context.registerAbility(new AbilityN());
        context.registerBusiness(new BusinessUsedAbilityPriorityDuplicate());
        e = assertThrows(ExtensionException.class, context::validateContext);
        assertEquals("business BusinessUsedAbilityPriorityDuplicate used ability priority 200 duplicate", e.getMessage());

        context = new DefaultExtContext<>(false, false);
        context.registerAbility(new AbilityM());
        context.registerAbility(new AbilityN());
        context.registerAbility(new ExtDefaultAbilityInvalid());
        context.registerBusiness(new BusinessUsedAbilityPriority());
        e = assertThrows(ExtensionException.class, context::validateContext);
        assertEquals("default ability should implements all extension interface, but current default ability not implements extension [io.github.xiaoshicae.extension.core.ExtA]", e.getMessage());

        context = new DefaultExtContext<>(false, false);
        context.registerAbility(new AbilityM());
        context.registerAbility(new AbilityN());
        context.registerAbility(new ExtDefaultAbility());
        context.registerBusiness(new BusinessUsedAbilityPriority());
    }