# Runtime Discovery / Dynamic Binding

> Every principle in this category is listed as a record.

Page: Ontology · Principles
Canonical: https://banes-lab.com/ontology#arch-category-runtime-discovery-dynamic-binding

Every principle in this category is listed as a record. Each record carries its kind, its severity, the scopes it applies at and the layer it lives in, then the edge relations that join it to other records, the records that point back at it, the contracts that answer to it and the tensions it takes part in. The descriptors say how it is violated, detected, measured, repaired and enforced. Where the record carries one, an exemplar shows the shape before and after the principle is applied.

Relations diagram

The relations inside this category.

```mermaid
flowchart LR
n_runtime_discovery["Runtime Discovery"]
n_service_discovery["Service Discovery"]
n_auto_discovery["Auto-Discovery"]
n_dynamic_binding["Dynamic Binding"]
n_late_binding["Late Binding"]
n_runtime_binding["Runtime Binding"]
n_dynamic_dispatch["Dynamic Dispatch"]
n_runtime_extensibility["Runtime Extensibility"]
n_runtime_discovery --> n_runtime_extensibility
n_runtime_discovery --> n_service_discovery
n_auto_discovery --> n_runtime_discovery
n_late_binding --> n_dynamic_binding
n_late_binding --> n_runtime_extensibility
n_runtime_binding --> n_dynamic_binding
```

### Runtime Discovery

- Kind: [mechanism](https://banes-lab.com/records/kind/mechanism.md)
- Severity: contextual
- Scope: runtime, plugin, service
- Layer: [Extensibility Core](https://banes-lab.com/records/layer/extensibility-core.md)

Details

Requires
[Metadata](https://banes-lab.com/records/lex/metadata.md), [Registry/Discovery Mechanism](https://banes-lab.com/records/lex/registry-discovery-mechanism.md)

Reinforces
[Runtime Extensibility](https://banes-lab.com/records/arch/runtime-extensibility.md)

Enables
[Plugin Architecture](https://banes-lab.com/records/arch/plugin-architecture.md), [Service Discovery](https://banes-lab.com/records/arch/service-discovery.md)

In tension with
[Predictability](https://banes-lab.com/records/arch/predictability.md), [Static Analysis](https://banes-lab.com/records/arch/static-analysis.md)

Conflicts with
[Static Linking](https://banes-lab.com/records/lex/static-linking.md)

Referenced by
[Self-Describing Architecture](https://banes-lab.com/records/arch/self-describing-architecture.md), [Metadata-Driven Design](https://banes-lab.com/records/arch/metadata-driven-design.md), [Capability Declaration](https://banes-lab.com/records/arch/capability-declaration.md), [Manifest-Based Design](https://banes-lab.com/records/arch/manifest-based-design.md), [Reflection](https://banes-lab.com/records/arch/reflection.md), [Auto-Discovery](https://banes-lab.com/records/arch/auto-discovery.md)

Contracts
[Runtime Discovery](https://banes-lab.com/records/algo/runtime-discovery.md)

Tensions
[Runtime Discovery Predictability](https://banes-lab.com/records/tension/predictability-runtime-discovery.md), [Runtime Discovery Static Analysis](https://banes-lab.com/records/tension/runtime-discovery-static-analysis.md)

Violated by
hardcoded dependency discovery

Detected by
manual class/service lists

Measured by
discovery coverage

Refactored by
Add Registry, Add Scanner, Add Manifest

Enforced by
startup validation

Before

```typescript
import { FooHandler } from "./foo-handler";
import { BarHandler } from "./bar-handler";
const handlers = [new FooHandler(), new BarHandler()];
```

After

```typescript
const modules = await discover<HandlerModule>("./handlers/*.handler.js");
const handlers = modules.map(module => module.create());
```

### Service Discovery

- Kind: [mechanism](https://banes-lab.com/records/kind/mechanism.md)
- Severity: contextual
- Scope: service, network, runtime
- Layer: [Extensibility Core](https://banes-lab.com/records/layer/extensibility-core.md)

Details

Requires
[Service Registry](https://banes-lab.com/records/arch/service-registry.md), [Health Checks](https://banes-lab.com/records/arch/health-checks.md)

Reinforces
[Scalability](https://banes-lab.com/records/arch/scalability.md), [Resilience](https://banes-lab.com/records/arch/resilience.md)

Enables
[Dynamic Routing](https://banes-lab.com/records/lex/dynamic-routing.md), [Failover](https://banes-lab.com/records/arch/failover.md)

In tension with
[Operational Complexity](https://banes-lab.com/records/lex/operational-complexity.md)

Conflicts with
[Hardcoded Endpoints](https://banes-lab.com/records/lex/hardcoded-endpoints.md)

Referenced by
[Runtime Discovery](https://banes-lab.com/records/arch/runtime-discovery.md)

Tensions
[Service Discovery Operational Complexity](https://banes-lab.com/records/tension/operational-complexity-service-discovery.md)

Violated by
fixed service addresses in code

Detected by
hardcoded URLs, missing registry lookup

Measured by
dynamic resolution coverage

Refactored by
Introduce Discovery Client, Externalize Endpoint

Enforced by
config scans, deployment policy

Before

```typescript
const fooUrl = "http://10.0.0.14:8080";
await http.get(`${fooUrl}/foo/${id}`);
```

After

```typescript
const endpoint = await serviceDiscovery.resolve("foo-service");
await http.get(new URL(`/foo/${id}`, endpoint));
```

### Auto-Discovery

- Kind: [mechanism](https://banes-lab.com/records/kind/mechanism.md)
- Severity: contextual
- Scope: plugin, module, service
- Layer: [Extensibility Core](https://banes-lab.com/records/layer/extensibility-core.md)

Details

Requires
[Metadata](https://banes-lab.com/records/lex/metadata.md), [Conventions](https://banes-lab.com/records/lex/conventions.md)

Reinforces
[Runtime Discovery](https://banes-lab.com/records/arch/runtime-discovery.md)

Enables
[Self-Registration](https://banes-lab.com/records/lex/self-registration.md)

In tension with
[Startup Cost](https://banes-lab.com/records/lex/startup-cost.md)

Conflicts with
[Manual Registration](https://banes-lab.com/records/lex/manual-registration.md)

Tensions
[Auto-Discovery Startup Cost](https://banes-lab.com/records/tension/auto-discovery-startup-cost.md)

Violated by
manual enumeration of discoverable components

Detected by
static lists of handlers/plugins

Measured by
manual registration count

Refactored by
Add Scanner, Add Annotation, Add Manifest

Enforced by
registry validation

Before

```typescript
register(new FooPlugin());
register(new BarPlugin());
register(new BazPlugin());
```

After

```typescript
for (const plugin of await scan<Plugin>("./plugins/*.plugin.js")) register(plugin);
```

### Dynamic Binding

- Kind: [mechanism](https://banes-lab.com/records/kind/mechanism.md)
- Severity: contextual
- Scope: runtime, interface, plugin
- Layer: [Extensibility Core](https://banes-lab.com/records/layer/extensibility-core.md)

Details

Requires
[Abstraction](https://banes-lab.com/records/arch/abstraction.md), [Runtime Resolution](https://banes-lab.com/records/lex/runtime-resolution.md)

Reinforces
[Polymorphism](https://banes-lab.com/records/arch/polymorphism.md), [Extensibility](https://banes-lab.com/records/lex/extensibility.md)

Enables
[Plugin Swap](https://banes-lab.com/records/lex/plugin-swap.md)

In tension with
[Static Safety](https://banes-lab.com/records/lex/static-safety.md)

Conflicts with
[Compile-Time Binding](https://banes-lab.com/records/lex/compile-time-binding.md)

Referenced by
[Capability Declaration](https://banes-lab.com/records/arch/capability-declaration.md), [Reflection](https://banes-lab.com/records/arch/reflection.md), [Late Binding](https://banes-lab.com/records/arch/late-binding.md), [Runtime Binding](https://banes-lab.com/records/arch/runtime-binding.md)

Tensions
[Dynamic Binding Static Safety](https://banes-lab.com/records/tension/dynamic-binding-static-safety.md)

Violated by
fixed concrete binding where runtime selection required

Detected by
hardcoded implementation selection

Measured by
runtime binding coverage

Refactored by
Introduce Factory, [Registry](https://banes-lab.com/records/lex/registry.md), Strategy

Enforced by
integration tests

Before

```typescript
const formatter = new JsonFooFormatter();
formatter.format(foo);
```

After

```typescript
const formatter = formatterRegistry.get(config.format);
if (!formatter) throw new Error(`unknown formatter: ${config.format}`);
formatter.format(foo);
```

### Late Binding

- Kind: [mechanism](https://banes-lab.com/records/kind/mechanism.md)
- Severity: contextual
- Scope: runtime, plugin, module
- Layer: [Extensibility Core](https://banes-lab.com/records/layer/extensibility-core.md)

Details

Requires
[Dynamic Binding](https://banes-lab.com/records/arch/dynamic-binding.md)

Reinforces
[Runtime Extensibility](https://banes-lab.com/records/arch/runtime-extensibility.md)

Enables
[Deferred Implementation Choice](https://banes-lab.com/records/lex/deferred-implementation-choice.md)

In tension with
[Predictability](https://banes-lab.com/records/arch/predictability.md)

Conflicts with
[Early Binding](https://banes-lab.com/records/lex/early-binding.md)

Tensions
[Late Binding Predictability](https://banes-lab.com/records/tension/late-binding-predictability.md)

Violated by
premature concrete resolution

Detected by
compile-time dependency on runtime extension

Measured by
late-bound extension count

Refactored by
Add Interface, Defer Resolution, Add Registry

Enforced by
dependency checks

Before

```typescript
const store = new SqlFooStore();
export const fooService = new FooService(store);
```

After

```typescript
export function bootstrap(config: Config) {
const store = storeRegistry.create(config.fooStore);
return new FooService(store);
}
```

### Runtime Binding

- Kind: [mechanism](https://banes-lab.com/records/kind/mechanism.md)
- Severity: contextual
- Scope: runtime, plugin, service
- Layer: [Extensibility Core](https://banes-lab.com/records/layer/extensibility-core.md)

Details

Requires
[Runtime Discovery or Configuration](https://banes-lab.com/records/lex/runtime-discovery-or-configuration.md)

Reinforces
[Dynamic Binding](https://banes-lab.com/records/arch/dynamic-binding.md)

Enables
[Environment-Specific Composition](https://banes-lab.com/records/lex/environment-specific-composition.md)

In tension with
[Debugging](https://banes-lab.com/records/lex/debugging.md)

Conflicts with
[Static Wiring](https://banes-lab.com/records/lex/static-wiring.md)

Referenced by
[Service Registry](https://banes-lab.com/records/arch/service-registry.md)

Tensions
[Runtime Binding Debugging](https://banes-lab.com/records/tension/debugging-runtime-binding.md)

Violated by
compile-time wiring of runtime choices

Detected by
fixed binding tables

Measured by
configurable binding coverage

Refactored by
Add DI Container, Add Registry

Enforced by
composition root tests

Before

```typescript
import { FooPolicy } from "./foo-policy";
const policy = new FooPolicy();
```

After

```typescript
const policyModule = await import(config.fooPolicyModule);
const policy: FooPolicy = policyModule.create(config.fooPolicyOptions);
```

### Dynamic Dispatch

- Kind: [mechanism](https://banes-lab.com/records/kind/mechanism.md)
- Severity: recommended
- Scope: method, interface, runtime
- Layer: [Extensibility Core](https://banes-lab.com/records/layer/extensibility-core.md)

Details

Requires
[Polymorphism](https://banes-lab.com/records/arch/polymorphism.md)

Reinforces
[Open/Closed Principle (OCP)](https://banes-lab.com/records/arch/open-closed.md)

Enables
[Replace Conditional with Polymorphism](https://banes-lab.com/records/lex/replace-conditional-with-polymorphism.md)

In tension with
[Traceability](https://banes-lab.com/records/arch/traceability.md)

Conflicts with
[Type-Switch Dispatch](https://banes-lab.com/records/lex/type-switch-dispatch.md)

Referenced by
[Polymorphism](https://banes-lab.com/records/arch/polymorphism.md)

Tensions
[Dynamic Dispatch Traceability](https://banes-lab.com/records/tension/dynamic-dispatch-traceability.md)

Violated by
manual dispatch over concrete type

Detected by
switch/if chains on type

Measured by
conditional dispatch count

Refactored by
Introduce Polymorphic Method, Strategy

Enforced by
lint rules, [review](https://banes-lab.com/records/lex/review.md)

Before

```typescript
function execute(kind: string, foo: Foo) {
if (kind === "save") return saveFoo(foo);
if (kind === "publish") return publishFoo(foo);
}
```

After

```typescript
const commands: Record<string, (foo: Foo) => unknown> = {
save: saveFoo,
publish: publishFoo,
};
function execute(kind: string, foo: Foo) {
const command = commands[kind];
if (!command) throw new Error(`unknown command ${kind}`);
return command(foo);
}
```

### Runtime Extensibility

- Kind: [quality-attribute](https://banes-lab.com/records/kind/quality-attribute.md)
- Severity: contextual
- Scope: runtime, plugin, system
- Layer: [Extensibility Core](https://banes-lab.com/records/layer/extensibility-core.md)

Details

Requires
[Extension Points](https://banes-lab.com/records/arch/extension-points.md), [Stable Interfaces](https://banes-lab.com/records/arch/stable-interfaces.md)

Reinforces
[Plugin Architecture](https://banes-lab.com/records/arch/plugin-architecture.md), [Open/Closed Principle (OCP)](https://banes-lab.com/records/arch/open-closed.md)

Enables
[Capability Addition without Core Modification](https://banes-lab.com/records/lex/capability-addition-without-core-modification.md)

In tension with
[Predictability](https://banes-lab.com/records/arch/predictability.md), [Security](https://banes-lab.com/records/lex/security.md)

Conflicts with
[Closed Static Core](https://banes-lab.com/records/lex/closed-static-core.md)

Referenced by
[Prototype Pattern](https://banes-lab.com/records/arch/prototype-pattern.md), [Runtime Code Generation](https://banes-lab.com/records/arch/runtime-code-generation.md), [Plugin Architecture](https://banes-lab.com/records/arch/plugin-architecture.md), [Feature Toggle](https://banes-lab.com/records/arch/feature-toggle.md), [Runtime Discovery](https://banes-lab.com/records/arch/runtime-discovery.md), [Late Binding](https://banes-lab.com/records/arch/late-binding.md)

Contracts
[Runtime Extensibility](https://banes-lab.com/records/algo/runtime-extensibility.md)

Tensions
[Runtime Extensibility Predictability](https://banes-lab.com/records/tension/predictability-runtime-extensibility.md), [Runtime Extensibility Security](https://banes-lab.com/records/tension/runtime-extensibility-security.md)

Violated by
modifying core for every extension

Detected by
repeated core changes for variants

Measured by
extension/core-change ratio

Refactored by
Add Extension Point, Add Plugin Interface

Enforced by
extension conformance tests

Before

```typescript
switch (pluginName) {
case "foo": return new FooPlugin();
case "bar": return new BarPlugin();
}
```

After

```typescript
export function registerPlugin(name: string, create: () => Plugin) {
pluginRegistry.set(name, create);
}
const plugin = pluginRegistry.get(pluginName)?.();
```

## Links to

- [mechanism](https://banes-lab.com/records/kind/mechanism.md)
- [Extensibility Core](https://banes-lab.com/records/layer/extensibility-core.md)
- [Metadata](https://banes-lab.com/records/lex/metadata.md)
- [Registry/Discovery Mechanism](https://banes-lab.com/records/lex/registry-discovery-mechanism.md)
- [Runtime Extensibility](https://banes-lab.com/records/arch/runtime-extensibility.md)
- [Plugin Architecture](https://banes-lab.com/records/arch/plugin-architecture.md)
- [Service Discovery](https://banes-lab.com/records/arch/service-discovery.md)
- [Predictability](https://banes-lab.com/records/arch/predictability.md)
- [Static Analysis](https://banes-lab.com/records/arch/static-analysis.md)
- [Static Linking](https://banes-lab.com/records/lex/static-linking.md)
- [Self-Describing Architecture](https://banes-lab.com/records/arch/self-describing-architecture.md)
- [Metadata-Driven Design](https://banes-lab.com/records/arch/metadata-driven-design.md)
- [Capability Declaration](https://banes-lab.com/records/arch/capability-declaration.md)
- [Manifest-Based Design](https://banes-lab.com/records/arch/manifest-based-design.md)
- [Reflection](https://banes-lab.com/records/arch/reflection.md)
- [Auto-Discovery](https://banes-lab.com/records/arch/auto-discovery.md)
- [Runtime Discovery](https://banes-lab.com/records/algo/runtime-discovery.md)
- [Runtime Discovery / Predictability](https://banes-lab.com/records/tension/predictability-runtime-discovery.md)
- [Runtime Discovery / Static Analysis](https://banes-lab.com/records/tension/runtime-discovery-static-analysis.md)
- [Service Registry](https://banes-lab.com/records/arch/service-registry.md)
- [Health Checks](https://banes-lab.com/records/arch/health-checks.md)
- [Scalability](https://banes-lab.com/records/arch/scalability.md)
- [Resilience](https://banes-lab.com/records/arch/resilience.md)
- [Dynamic Routing](https://banes-lab.com/records/lex/dynamic-routing.md)
- [Failover](https://banes-lab.com/records/arch/failover.md)
- [Operational Complexity](https://banes-lab.com/records/lex/operational-complexity.md)
- [Hardcoded Endpoints](https://banes-lab.com/records/lex/hardcoded-endpoints.md)
- [Runtime Discovery](https://banes-lab.com/records/arch/runtime-discovery.md)
- [Service Discovery / Operational Complexity](https://banes-lab.com/records/tension/operational-complexity-service-discovery.md)
- [Conventions](https://banes-lab.com/records/lex/conventions.md)
- [Self-Registration](https://banes-lab.com/records/lex/self-registration.md)
- [Startup Cost](https://banes-lab.com/records/lex/startup-cost.md)
- [Manual Registration](https://banes-lab.com/records/lex/manual-registration.md)
- [Auto-Discovery / Startup Cost](https://banes-lab.com/records/tension/auto-discovery-startup-cost.md)
- [Abstraction](https://banes-lab.com/records/arch/abstraction.md)
- [Runtime Resolution](https://banes-lab.com/records/lex/runtime-resolution.md)
- [Polymorphism](https://banes-lab.com/records/arch/polymorphism.md)
- [Extensibility](https://banes-lab.com/records/lex/extensibility.md)
- [Plugin Swap](https://banes-lab.com/records/lex/plugin-swap.md)
- [Static Safety](https://banes-lab.com/records/lex/static-safety.md)
- [Compile-Time Binding](https://banes-lab.com/records/lex/compile-time-binding.md)
- [Late Binding](https://banes-lab.com/records/arch/late-binding.md)
- [Runtime Binding](https://banes-lab.com/records/arch/runtime-binding.md)
- [Dynamic Binding / Static Safety](https://banes-lab.com/records/tension/dynamic-binding-static-safety.md)
- [Registry](https://banes-lab.com/records/lex/registry.md)
- [Dynamic Binding](https://banes-lab.com/records/arch/dynamic-binding.md)
- [Deferred Implementation Choice](https://banes-lab.com/records/lex/deferred-implementation-choice.md)
- [Early Binding](https://banes-lab.com/records/lex/early-binding.md)
- [Late Binding / Predictability](https://banes-lab.com/records/tension/late-binding-predictability.md)
- [Runtime Discovery or Configuration](https://banes-lab.com/records/lex/runtime-discovery-or-configuration.md)
- [Environment-Specific Composition](https://banes-lab.com/records/lex/environment-specific-composition.md)
- [Debugging](https://banes-lab.com/records/lex/debugging.md)
- [Static Wiring](https://banes-lab.com/records/lex/static-wiring.md)
- [Runtime Binding / Debugging](https://banes-lab.com/records/tension/debugging-runtime-binding.md)
- [Open/Closed Principle (OCP)](https://banes-lab.com/records/arch/open-closed.md)
- [Replace Conditional with Polymorphism](https://banes-lab.com/records/lex/replace-conditional-with-polymorphism.md)
- [Traceability](https://banes-lab.com/records/arch/traceability.md)
- [Type-Switch Dispatch](https://banes-lab.com/records/lex/type-switch-dispatch.md)
- [Dynamic Dispatch / Traceability](https://banes-lab.com/records/tension/dynamic-dispatch-traceability.md)
- [Review](https://banes-lab.com/records/lex/review.md)
- [quality-attribute](https://banes-lab.com/records/kind/quality-attribute.md)
- [Extension Points](https://banes-lab.com/records/arch/extension-points.md)
- [Stable Interfaces](https://banes-lab.com/records/arch/stable-interfaces.md)
- [Capability Addition without Core Modification](https://banes-lab.com/records/lex/capability-addition-without-core-modification.md)
- [Security](https://banes-lab.com/records/lex/security.md)
- [Closed Static Core](https://banes-lab.com/records/lex/closed-static-core.md)
- [Prototype Pattern](https://banes-lab.com/records/arch/prototype-pattern.md)
- [Runtime Code Generation](https://banes-lab.com/records/arch/runtime-code-generation.md)
- [Feature Toggle](https://banes-lab.com/records/arch/feature-toggle.md)
- [Runtime Extensibility](https://banes-lab.com/records/algo/runtime-extensibility.md)
- [Runtime Extensibility / Predictability](https://banes-lab.com/records/tension/predictability-runtime-extensibility.md)
- [Runtime Extensibility / Security](https://banes-lab.com/records/tension/runtime-extensibility-security.md)

## Linked from

- [The layer topology](https://banes-lab.com/ontology/schema/the-layer-topology.md)
- [The membership](https://banes-lab.com/ontology/schema/the-membership.md)
