Initialize client¶
Before any request can be issued, an HttpJsonClient instance must have a base URL and a ClientInfo (machine name, application ID, user name) associated with it, either supplied at construction or set afterward through SetClientInfo.
| Field | Value |
|---|---|
| Operation ID | OP-01 |
| Trigger | Construction of HttpJsonClient, or a call to SetClientInfo on a resolved instance |
| Inputs | Base URL; ClientInfo (machine name, application ID, user name) or its constituent strings; optional timeout override in milliseconds |
| Outputs | An initialized HttpJsonClient ready to accept requests, or an instance that will throw ClientNotInitializedException on first use if initialization is incomplete |
| Primary components | HttpJsonClient.HttpJsonClient(string, ClientInfo), HttpJsonClient.HttpJsonClient(string, string, string, string), HttpJsonClient.HttpJsonClient(), HttpJsonClient.SetClientInfo, ClientInfo.ClientInfo |
| Entry point | src/SAIF.NetCore.HttpClients/SAIF.NetCore.HttpClients/SAIF.NetCore.HttpClients/HttpJsonClient/HttpJsonClient.cs |
Steps¶
- The consumer constructs
HttpJsonClientusing one of three paths: new HttpJsonClient(baseUrl, clientInfo)—baseUrlis null-checked and throwsArgumentNullExceptionif null;clientInfois not null-checked on this overload, so a nullclientInfois accepted silently here (BR-HTTP-02).new HttpJsonClient(baseUrl, userName, machineName, applicationId)— builds aClientInfointernally, whose constructor null-checks each of machine name, application ID, and user name and throwsArgumentNullExceptionimmediately if any is null (BR-HTTP-03).new HttpJsonClient()— leaves the instance uninitialized; this is the only constructor dependency injection can satisfy, so DI-resolved instances require a subsequentSetClientInfocall before use*.- If initialization was deferred or needs updating, the consumer calls
SetClientInfo(baseUrl, userName, machineName, applicationId, msTimeoutOverride)or the four-argument overload without a timeout. Unlike the two-argument constructor,SetClientInfovalidates immediately rather than deferring to the next request, but the call is not atomic: the five-argument overload stores a positivemsTimeoutOverrideon the instance first, then the shared four-argument logic constructs and assigns a newClientInfobuilt fromuserName,machineName, andapplicationId, and only after that succeeds does it construct and assign a newUribuilt frombaseUrl. A failingClientInfoconstruction (null identity argument) or a failingUriconstruction (invalidbaseUrl) throws immediately, but any state mutation that already completed before the failure point — the stored timeout, and, for a badbaseUrl, the newly assignedClientInfo— remains in effect on the instance. - The timeout override is stored only when greater than 0; a value of 0 or less leaves any previously stored override unchanged rather than resetting it (BR-HTTP-06).
- This operation has two genuinely deferred-failure paths, both surfacing only on the first subsequent verb method call rather than at configuration time: the two-argument constructor called with a non-null
baseUrlbut a nullclientInfo(step 1), and the parameterless constructor used without ever callingSetClientInfoafterward. In both casesClientInfoand/or the base URI remain unset, and the first verb method invoked afterward throwsClientNotInitializedException(BR-HTTP-01). - The instance is now ready to accept authentication configuration (see Configure authentication), option configuration (see Configure options), and request execution (see Execute request).
Process flow¶
The following diagram visualizes the initialization paths, the actual mutation order inside SetClientInfo, and the deferred-failure behavior when initialization is incomplete.
flowchart TD
Start([Consumer obtains HttpJsonClient]) --> Choice{Construction path?}
Choice -->|"baseUrl + ClientInfo"| C1["Null-check baseUrl only;<br>null clientInfo accepted silently"]
Choice -->|"baseUrl + identity strings"| C2["Build ClientInfo immediately<br>(throws if any field is null)"]
Choice -->|Parameterless / DI| C3["Uninitialized instance"]
C3 --> SetInfo["SetClientInfo(...)"]
SetInfo --> StoreTimeout{"5-arg overload with<br>msTimeoutOverride > 0?"}
StoreTimeout -->|Yes| StoredTimeout["Store timeout override<br>(first mutation)"]
StoreTimeout -->|No| SkipTimeout["Leave any previously stored<br>override unchanged"]
StoredTimeout --> BuildClientInfo
SkipTimeout --> BuildClientInfo
BuildClientInfo["Construct and assign<br>new ClientInfo(...)<br>(throws on null identity field)"] --> BuildUri["Construct and assign<br>new Uri(baseUrl)<br>(throws on invalid baseUrl)"]
BuildUri --> Ready([Ready for requests])
C2 --> Ready
C1 --> ClientInfoCheck{"clientInfo was non-null?"}
ClientInfoCheck -->|Yes| Ready
ClientInfoCheck -->|No| Fail(["First request throws<br>ClientNotInitializedException"])
C3 -->|"No SetClientInfo call made"| Fail
Failure and edge-case behavior¶
- A null
baseUrlin the two-argument constructor fails immediately withArgumentNullException, before any request is attempted. - A null
clientInfopassed to the two-argument constructor is accepted silently, and a parameterless-constructed instance that never receives aSetClientInfocall is likewise left uninitialized; both gaps are discovered only when the first verb method throwsClientNotInitializedException— these are the two genuinely deferred-failure paths through this operation. - Calling
SetClientInfowith a null or invalidbaseUrl, or a nulluserName/machineName/applicationId, fails immediately inside the call itself (ArgumentNullExceptionfromClientInfo's constructor, or an exception from theUriconstructor), but the call is not atomic: the positive timeout override (if supplied) and a successfully constructedClientInfoare stored on the instance before theUriconstruction is attempted, so a failingbaseUrlcan leave the instance with a newly updatedClientInfo/timeout and its previous base URI. - A timeout override of 0 or a negative value passed to
SetClientInfois not stored; any previously stored override remains unchanged. A value greater than 600000 ms is accepted and stored bySetClientInfobut ignored at request time (BR-HTTP-06).
Related documentation¶
Note: Statements marked with
*were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts.
Sources¶
src/SAIF.NetCore.HttpClients/SAIF.NetCore.HttpClients/SAIF.NetCore.HttpClients/HttpJsonClient/HttpJsonClient.cssrc/SAIF.NetCore.HttpClients/SAIF.NetCore.HttpClients/SAIF.NetCore.HttpClients/ClientInfo.cs