# IIdentity and IIdentityResolver: Extension Routing in the cp-ddd-framework

> Understand the IIdentity and IIdentityResolver in cp-ddd-framework. Discover how they power extension routing by mapping business data to specific extension implementations.

- Repository: [Funky Gao/cp-ddd-framework](https://github.com/funkygao/cp-ddd-framework)
- Tags: internals
- Published: 2026-03-02

---

**In the cp-ddd-framework, `IIdentity` represents the business data to be routed while `IIdentityResolver` provides the matching logic that determines which extension implementation should handle that specific identity, together forming the core extension routing mechanism that maps domain objects to concrete extension points.**

The `funkygao/cp-ddd-framework` implements a dynamic extension routing system that selects business logic implementations based on domain context. At the heart of this system are two key interfaces: `IIdentity` and `IIdentityResolver`. Understanding how these components collaborate enables developers to build flexible, domain-driven extension points that route requests to the appropriate business logic based on runtime identity.

## The Role of IIdentity in Extension Routing

**`IIdentity`** represents a business identity—a set of domain attributes that describe a concrete business scenario such as an order, SKU, or shipment. Rather than acting as a dedicated data transfer object, this interface is typically implemented by existing domain models within your application.

The interface resides in [`dddplus-spec/src/main/java/io/github/dddplus/ext/IIdentity.java`](https://github.com/funkygao/cp-ddd-framework/blob/main/dddplus-spec/src/main/java/io/github/dddplus/ext/IIdentity.java) and provides the foundation for all routing decisions. Any domain class can implement this interface to become routable:

```java
public class ShipmentOrder implements IIdentity {
    // Domain-specific attributes and methods
}

```

## How IIdentityResolver Implements Routing Logic

**`IIdentityResolver`** serves as a business-identity matcher or plug-in that determines whether a given identity belongs to a specific business scenario. Defined in [`dddplus-spec/src/main/java/io/github/dddplus/ext/IIdentityResolver.java`](https://github.com/funkygao/cp-ddd-framework/blob/main/dddplus-spec/src/main/java/io/github/dddplus/ext/IIdentityResolver.java), this interface requires implementing a single `match` method that evaluates the identity against business rules.

Each resolver targets a specific identity type and implements custom matching logic:

```java
public class PresaleResolver implements IIdentityResolver<ShipmentOrder> {
    @Override
    public boolean match(@NonNull ShipmentOrder identity) {
        return identity.isPresale();  // Business rule evaluation
    }
}

```

Routers aggregate multiple resolvers to handle complex routing scenarios. The framework supports both exclusive and cumulative matching strategies through the resolver composition pattern.

## Coordinating Identity and Resolver in the Routing Flow

The interaction between `IIdentity` and `IIdentityResolver` follows a clear execution path from domain object to extension implementation. The framework provides two primary mechanisms for this coordination: the `matchAny` utility method and policy-based routing through `IPolicy`.

### The matchAny Utility Method

The `IIdentity` interface includes a default `matchAny` method that enables cumulative routing strategies. This utility iterates over provided resolvers and returns `true` as soon as one matches, allowing identities to be tested against multiple scenarios efficiently.

As demonstrated in [`dddplus-test/src/test/java/io/github/dddplus/DesignTest.java`](https://github.com/funkygao/cp-ddd-framework/blob/main/dddplus-test/src/test/java/io/github/dddplus/DesignTest.java):

```java
@Test
void matchAny() {
    // task implements IIdentity
    assertFalse(task.matchAny(presalePattern));
    assertTrue(task.matchAny(pledgePattern));
    assertTrue(task.matchAny(presalePattern, pledgePattern));
}

```

This method enables routers to implement logic where an identity may satisfy multiple business patterns or require exclusive matching against specific resolvers.

### Router Execution and Policy Resolution

At runtime, `BaseRouter` (or custom router implementations) orchestrates the lookup of concrete extensions based on resolver outcomes. When a policy is employed, the framework utilizes `IPolicy`, which represents a single-extension routing strategy embedding the matching logic directly.

The runtime resolution occurs in [`dddplus-runtime/src/main/java/io/github/dddplus/runtime/registry/PolicyDef.java`](https://github.com/funkygao/cp-ddd-framework/blob/main/dddplus-runtime/src/main/java/io/github/dddplus/runtime/registry/PolicyDef.java):

```java
final String extensionCode = policyBean.extensionCode(identity);
if (extensionCode == null) { /* no extension */ }
return extensionDefMap.get(extensionCode);

```

Here, the `extensionCode` method evaluates the identity—potentially using `matchAny` with configured resolvers—and returns the identifier used to retrieve the concrete extension bean from the registry.

## Practical Implementation Example

The following implementation demonstrates the complete flow from identity definition through resolver creation to router configuration:

```java
// 1️⃣ Define a business identity
public class FooIdentity implements IIdentity {
    private final String sku;
    public FooIdentity(String sku) { this.sku = sku; }
    public String sku() { return sku; }
}

// 2️⃣ Implement a resolver for "premium" SKUs
public class PremiumResolver implements IIdentityResolver<FooIdentity> {
    @Override
    public boolean match(@NonNull FooIdentity identity) {
        return identity.sku().startsWith("PREM-");
    }
}

// 3️⃣ Use the resolver in a router via matchAny
public class FooRouter extends BaseRouter<IFooExt, FooIdentity> {
    private final PremiumResolver premiumResolver = new PremiumResolver();

    @Override
    public String extensionCode(@NonNull FooIdentity identity) {
        // If identity belongs to the premium scenario, bind to "premium" extension
        if (identity.matchAny(premiumResolver)) {
            return "premium";
        }
        // fallback
        return "default";
    }
}

```

## Summary

- **`IIdentity`** encapsulates the business scenario data that drives routing decisions, typically implemented by existing domain models.
- **`IIdentityResolver`** provides pluggable matching logic to identify whether an identity belongs to a specific business context.
- The **`matchAny`** method enables cumulative or exclusive routing strategies by iterating over multiple resolvers until a match is found.
- **`BaseRouter`** and **`PolicyDef`** orchestrate the final lookup of concrete extension implementations based on resolver outcomes and extension codes.

## Frequently Asked Questions

### What is the difference between IIdentity and IIdentityResolver?

**`IIdentity`** represents the data contract—what is being routed—containing the domain attributes that describe a business scenario. **`IIdentityResolver`** represents the decision logic—how to determine if an identity fits a specific pattern—implementing the `match` method that evaluates business rules against the identity's state.

### How does the matchAny method work in extension routing?

The `matchAny` method is a default implementation in the `IIdentity` interface (defined in [`IIdentity.java`](https://github.com/funkygao/cp-ddd-framework/blob/main/IIdentity.java)) that accepts one or more `IIdentityResolver` instances. It iterates through the provided resolvers and returns `true` immediately upon the first successful match, enabling efficient short-circuit evaluation for cumulative routing scenarios.

### Can multiple resolvers be used for the same identity?

Yes. The `matchAny` method specifically supports multiple resolvers, allowing a single identity to be evaluated against several business patterns simultaneously. This supports complex routing logic where an identity might qualify for multiple extension points or require cascading evaluation against different business rules.

### What role does IPolicy play in the extension routing mechanism?

**`IPolicy`** represents a single-extension routing strategy defined in [`dddplus-spec/src/main/java/io/github/dddplus/ext/IPolicy.java`](https://github.com/funkygao/cp-ddd-framework/blob/main/dddplus-spec/src/main/java/io/github/dddplus/ext/IPolicy.java). Unlike separate router configurations that use external resolvers, a policy implements `extensionCode(IIdentity)` directly to compute and return the extension code. The runtime invokes this method in [`PolicyDef.java`](https://github.com/funkygao/cp-ddd-framework/blob/main/PolicyDef.java) to resolve the concrete extension implementation without requiring explicit resolver aggregation in the router class.