---
title: Construct UC4 client
summary: Validates that the environment can run UC4 scheduling and caches the base URL and route.
status: draft
owner: SAIF Framework Platform Team
last_reviewed: 2026-10-02
library: SAIF.NetCore.Clients.UC4
reference_type: package
operation_id: OP-UC4-01
trigger: The DI container resolves IUC4Client, or a caller runs new UC4Client(env, http)
---

# Construct UC4 client

This operation runs once per `UC4Client` instance. It checks that the two settings the client needs exist in the Environment API, reads their values, and derives the caller-identity header value — before the instance can be used to schedule any job.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-UC4-01 |
| **Trigger** | DI container resolves `IUC4Client`, or a caller runs `new UC4Client(env, httpJsonClient)` |
| **Inputs** | `IEnvironmentClient env`, `IHttpJsonClient httpJsonClient` |
| **Outputs** | An instance with `ServiceUrl`, `ScheduleJobEndpoint`, and `ClientName` populated, and `IsConfigured = false` |
| **Primary components** | `UC4Client..ctor`, `UC4Client.EnsureSettingExists` |
| **Entry point** | `src/SAIF.NetCore.Clients.UC4/SAIF.NetCore.Clients.UC4/SAIF.NetCore.Clients.UC4/Services/UC4Client.cs` |

## Steps

1. Check that setting `uc4coreapi:url` exists ([BR-UC4-01](../business-rules.md#br-uc4-01-required-settings-must-exist-at-construction)).
   - Delegates to `SAIF.NetCore.EnvironmentClient`'s `BaseEnvironmentClient.HasSetting(configKey, section)`: start a tagged `ActivitySource` span, build the cache key from key and section, lazily load the section from the Environment API if not already cached, check the cache, and return a bool.
   - On failure (`false`): throw `NotSupportedException("UC4 Client cannot be ran in an environment where the environment key uc4coreapi.url does not exist.")`. Construction aborts.
2. Check that setting `uc4coreapi:schedulejobroute` exists ([BR-UC4-01](../business-rules.md#br-uc4-01-required-settings-must-exist-at-construction)).
   - Same callee as step 1.
   - On failure: same exception, naming `uc4coreapi.schedulejobroute`.

   > **Origin**: Steps 1–2 are implemented in [`HasSetting`](../../saif-netcore-environmentclient/operations/has-setting.md) (`SAIF.NetCore.EnvironmentClient`) and executed on behalf of this operation.
3. Read the `uc4coreapi:url` value into `ServiceUrl` ([BR-UC4-02](../business-rules.md#br-uc4-02-settings-existence-is-validated-independently-of-value-content)).
   - Delegates to `BaseEnvironmentClient.GetSettingValue(configKey, section)`, which returns `ConfigValue?.Value ?? ""` — a null value becomes an empty string with no error.
   - If empty: accepted silently here; fails later in [Schedule a UC4 job](op-uc4-02-schedule-job.md) step 2.
4. Read the `uc4coreapi:schedulejobroute` value into `ScheduleJobEndpoint` ([BR-UC4-02](../business-rules.md#br-uc4-02-settings-existence-is-validated-independently-of-value-content)).
   - Same callee as step 3.
   - If empty: accepted silently; the later POST targets `""` + `jobname` relative to the base URL.

   > **Origin**: Steps 3–4 are implemented in [`GetSettingValue`](../../saif-netcore-environmentclient/operations/get-setting-value.md) (`SAIF.NetCore.EnvironmentClient`) and executed on behalf of this operation.
5. Set `ClientName` to the assembly simple name, `"SAIF.NetCore.Clients.UC4"` ([BR-UC4-04](../business-rules.md#br-uc4-04-caller-identity-is-sent-via-fixed-and-caller-supplied-headers)).
6. Store the injected `IHttpJsonClient`.
   - No null-guard exists on either constructor argument. A null `env` causes a `NullReferenceException` in step 1. A null `httpJsonClient` fails later, in [Schedule a UC4 job](op-uc4-02-schedule-job.md).

## Process flow

```mermaid
flowchart TD
	Start([DI resolves IUC4Client / new UC4Client]) --> S1["Check uc4coreapi:url exists"]
	S1 --> D1{Exists?}
	D1 -->|No| Err1(["NotSupportedException: uc4coreapi.url"])
	D1 -->|Yes| S2["Check uc4coreapi:schedulejobroute exists"]
	S2 --> D2{Exists?}
	D2 -->|No| Err2(["NotSupportedException: uc4coreapi.schedulejobroute"])
	D2 -->|Yes| S3["Read ServiceUrl, ScheduleJobEndpoint"]
	S3 --> S4[Set ClientName from assembly name]
	S4 --> Ok(["Instance ready, IsConfigured=false"])
```

## Failure and edge-case behavior
- Missing `uc4coreapi:url` or `uc4coreapi:schedulejobroute`: `NotSupportedException`, construction aborts entirely.
- Present but empty values: construction succeeds; failures surface later in `ScheduleJob`.
- Null `IEnvironmentClient` argument: `NullReferenceException` during step 1*.

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)

> **Note:** Statements marked with * were inferred from code structure, naming conventions, or
> contextual evidence where direct confirmation was not available in source artifacts. Statements
> marked with ** could not be confirmed; treat as unknown until verified.

## Sources
- `src/SAIF.NetCore.Clients.UC4/SAIF.NetCore.Clients.UC4/SAIF.NetCore.Clients.UC4/Services/UC4Client.cs`
- `src/SAIF.NetCore.EnvironmentClient/SAIF.NetCore.EnvironmentClient/SAIF.NetCore.EnvironmentClient/BaseEnvironmentClient.cs` — declares `HasSetting`/`GetSettingValue`, the delegated behavior described in steps 1–4.
