|
49 | 49 | * Basic implementation of the service registry with simple dependency support. |
50 | 50 | */ |
51 | 51 | class CoreServiceRegistry implements ServiceRegistry, Scopes { |
| 52 | + private static final ResolvedType COMMON_CONFIG = ResolvedType.create("io.helidon.common.config.Config"); |
| 53 | + private static final ResolvedType CONFIG = ResolvedType.create("io.helidon.config.Config"); |
52 | 54 | private static final AtomicInteger COUNTER = new AtomicInteger(); |
53 | 55 |
|
54 | 56 | private final String id = String.valueOf(COUNTER.incrementAndGet()); |
@@ -549,53 +551,63 @@ <T> void set(Class<T> contract, T[] instances) { |
549 | 551 | stateWriteLock.lock(); |
550 | 552 | try { |
551 | 553 | ResolvedType contractType = ResolvedType.create(contract); |
552 | | - checkValidContract(contractType); |
553 | | - ServiceInfo serviceInfo = servicesByType.get(contractType.type()); |
554 | | - if (serviceInfo == null) { |
555 | | - Set<ServiceInfo> serviceInfos = new TreeSet<>(SERVICE_INFO_COMPARATOR); |
556 | | - |
557 | | - // we need to keep order of the instances; if somebody calls set, and then add, it may be tricky |
558 | | - double currentWeight = Weighted.DEFAULT_WEIGHT; |
559 | | - for (T instance : instances) { |
560 | | - // each instance will have its own descriptor |
561 | | - VirtualDescriptor vt = new VirtualDescriptor(contractType.type(), currentWeight, instance); |
562 | | - ServiceProvider<Object> provider = new ServiceProvider<>(this, |
563 | | - vt); |
564 | | - Activator<Object> activator = Activators.create(provider, instance); |
565 | | - |
566 | | - servicesByDescriptor.put(vt, new ServiceManager<>(this, |
567 | | - scopeSupplier(vt), |
568 | | - provider, |
569 | | - true, |
570 | | - () -> activator)); |
571 | | - serviceInfos.add(vt); |
572 | | - // reduce by a small number, so other things behave as expected |
573 | | - currentWeight -= 0.001; |
574 | | - } |
575 | | - // replace the instances |
576 | | - servicesByContract.put(contractType, serviceInfos); |
| 554 | + if (contractType.equals(CONFIG)) { |
| 555 | + // this is a temporary solution to our problem of two config interfaces, we want users to only set it once |
| 556 | + doSet(CONFIG, instances); |
| 557 | + doSet(COMMON_CONFIG, instances); |
577 | 558 | } else { |
578 | | - // this is a service instance, not contract implementation (i.e. the contract is actual service class) |
579 | | - ServiceProvider<Object> provider = new ServiceProvider<>(this, |
580 | | - (ServiceDescriptor<Object>) serviceInfo); |
581 | | - if (instances.length != 1) { |
582 | | - throw new ServiceRegistryException("Attempting to set a service provider with wrong number of instances. " |
583 | | - + "A service provider must have exactly one instance."); |
584 | | - } |
585 | | - Activator<Object> activator = Activators.create(provider, instances[0]); |
586 | | - servicesByDescriptor.put(serviceInfo, new ServiceManager<>(this, |
587 | | - scopeSupplier(serviceInfo), |
588 | | - provider, |
589 | | - true, |
590 | | - () -> activator)); |
| 559 | + doSet(contractType, instances); |
591 | 560 | } |
592 | | - // reset bindings, as build-time binding would ignore instances explicitly set |
593 | | - bindings.forgetContract(contractType); |
594 | 561 | } finally { |
595 | 562 | stateWriteLock.unlock(); |
596 | 563 | } |
597 | 564 | } |
598 | 565 |
|
| 566 | + private <T> void doSet(ResolvedType contractType, T[] instances) { |
| 567 | + checkValidContract(contractType); |
| 568 | + ServiceInfo serviceInfo = servicesByType.get(contractType.type()); |
| 569 | + if (serviceInfo == null) { |
| 570 | + Set<ServiceInfo> serviceInfos = new TreeSet<>(SERVICE_INFO_COMPARATOR); |
| 571 | + |
| 572 | + // we need to keep order of the instances; if somebody calls set, and then add, it may be tricky |
| 573 | + double currentWeight = Weighted.DEFAULT_WEIGHT; |
| 574 | + for (T instance : instances) { |
| 575 | + // each instance will have its own descriptor |
| 576 | + VirtualDescriptor vt = new VirtualDescriptor(contractType.type(), currentWeight, instance); |
| 577 | + ServiceProvider<Object> provider = new ServiceProvider<>(this, |
| 578 | + vt); |
| 579 | + Activator<Object> activator = Activators.create(provider, instance); |
| 580 | + |
| 581 | + servicesByDescriptor.put(vt, new ServiceManager<>(this, |
| 582 | + scopeSupplier(vt), |
| 583 | + provider, |
| 584 | + true, |
| 585 | + () -> activator)); |
| 586 | + serviceInfos.add(vt); |
| 587 | + // reduce by a small number, so other things behave as expected |
| 588 | + currentWeight -= 0.001; |
| 589 | + } |
| 590 | + // replace the instances |
| 591 | + servicesByContract.put(contractType, serviceInfos); |
| 592 | + } else { |
| 593 | + // this is a service instance, not contract implementation (i.e. the contract is actual service class) |
| 594 | + ServiceProvider<Object> provider = new ServiceProvider<>(this, |
| 595 | + (ServiceDescriptor<Object>) serviceInfo); |
| 596 | + if (instances.length != 1) { |
| 597 | + throw new ServiceRegistryException("Attempting to set a service provider with wrong number of instances. " |
| 598 | + + "A service provider must have exactly one instance."); |
| 599 | + } |
| 600 | + Activator<Object> activator = Activators.create(provider, instances[0]); |
| 601 | + servicesByDescriptor.put(serviceInfo, new ServiceManager<>(this, |
| 602 | + scopeSupplier(serviceInfo), |
| 603 | + provider, |
| 604 | + true, |
| 605 | + () -> activator)); |
| 606 | + } |
| 607 | + // reset bindings, as build-time binding would ignore instances explicitly set |
| 608 | + bindings.forgetContract(contractType); |
| 609 | + } |
| 610 | + |
599 | 611 | InterceptionMetadata interceptionMetadata() { |
600 | 612 | return interceptionMetadata; |
601 | 613 | } |
|
0 commit comments