---
title: Architecture
summary: How the proxy is constructed, configured, invoked, and disposed.
status: draft
owner: SAIF.Core documentation
last_reviewed: 2026-09-24
---

# Architecture

This repository reaches `ConnectInfo` through the generated `ConnectInfoSoapClient`, wrapped by the authored `DbConnectionServiceProxy`, which builds its own `BasicHttpBinding` and `EndpointAddress` in code rather than relying on the `app.config` endpoint.

## Proxy mechanism

| Aspect | Finding |
| --- | --- |
| Mechanism | Service Reference (svcutil) |
| Proxy type | `SAIF.Services.Web.Proxies.DbConnection.ConnectInfoSoapClient` (`internal`) |
| Base type | `System.ServiceModel.ClientBase<T>` |
| Contract type | `internal interface ConnectInfoSoap` |
| Constructed in | `DbConnectionServiceProxy` constructor (`Services/SAIF.Services.Web.Proxies/Legacy/DbConnectionsServiceProxy.cs:17-20`) |
| Binding configured in | Code |
| Address supplied by | Constructor argument (`serviceUrl`), itself sourced from `IEnvironmentService.GetConfigSetting("dbconnectionserviceurl")` |

## Architecture diagram

The following diagram visualizes how a call reaches the remote service.

```mermaid
flowchart TD
    CALLER["DbConnectionService.GetConnectionString"] --> WRAP["DbConnectionServiceProxy<br>hand-written wrapper"]
    WRAP --> BIND["Binding constructed<br>BasicHttpBinding (defaults)"]
    BIND --> ADDR["EndpointAddress<br>from dbconnectionserviceurl setting"]
    ADDR --> PROXY["ConnectInfoSoapClient<br>generated proxy"]
    PROXY --> REMOTE["Remote service<br>ConnectInfo (ASMX)"]
    WRAP --> DISPOSE["Close only<br>no Abort on fault"]
```

## Hand-written wrapper

| Field | Value |
| --- | --- |
| **Type** | `SAIF.Services.Web.Proxies.Legacy.DbConnectionServiceProxy` |
| **Source** | `Services/SAIF.Services.Web.Proxies/Legacy/DbConnectionsServiceProxy.cs` (file name differs from the class name) |
| **Visibility** | `public` |
| **Implements** | `IDisposable` |
| **Responsibility** | Validates the supplied service URL, constructs the generated `ConnectInfoSoapClient` with an explicit binding and address, and exposes `GetOracleConnectionString`/`GetSqlServerConnectionString` |
| **Proxy lifetime** | Shared — one `ConnectInfoSoapClient` is created in the wrapper's constructor and held for the wrapper's lifetime |

| Configuration applied | Value | Source |
| --- | --- | --- |
| `BasicHttpBinding` security mode | None declared — `BasicHttpBinding()` defaults*, so `BasicHttpSecurityMode.None` applies | `DbConnectionsServiceProxy.cs:18` |
| Transport client credential | None set | `DbConnectionsServiceProxy.cs:18-21` |
| `MaxReceivedMessageSize` | Not set — the WCF default of 65,536 bytes applies* | `DbConnectionsServiceProxy.cs:18` |
| `MaxBufferSize` | Not set — WCF default applies* | `DbConnectionsServiceProxy.cs:18` |
| Timeouts | None set — binding defaults apply* | `DbConnectionsServiceProxy.cs:18` |

## Endpoint resolution

| Environment | Address | Resolved from | Changeable without a rebuild |
| --- | --- | --- | --- |
| All | Unresolved from repository configuration** | `Services/SAIF.Services.Common/DbConnectionService.cs:21` (`environmentService.GetConfigSetting("dbconnectionserviceurl")`); the key is absent from every `environments.xml` and `*.config` file searched | Not determined from source** |

The `dbconnectionserviceurl` key could not be resolved to a value from this repository. `EnvironmentApi/App_Data/environments.xml` (all tracks), `EnvironmentApi.Tests/environments.xml`, and every `*.config` file were searched with no match. The only literal found is a unit-test mock, `http://saifonline/WebServices/wsDBConnections/ConnectInfo.asmx` (`Tests/SAIF.Services.Tests/Agencies/AgenciesTestBase.cs:19-20`), which is test data, not runtime configuration.

## Lifetime and disposal

| Aspect | Finding |
| --- | --- |
| Proxy lifetime | Per consuming instance — one `ConnectInfoSoapClient` is created per `DbConnectionServiceProxy` and reused for the owner's lifetime |
| Disposal | `Dispose()` calls `webService.Close()` (`DbConnectionsServiceProxy.cs:61-68`); there is no `Abort()` fallback |
| Faulted-channel handling | `Close()` on a faulted `ClientBase<T>` throws `CommunicationObjectFaultedException` and leaks the channel* |
| Thread safety | Not determined from source |

## Integration points

| System | Type | Purpose |
| --- | --- | --- |
| `ConnectInfo` | SOAP service | Resolves Oracle/SQL Server connection strings by pool code and instance |

## Related documentation
- [Client index](index.md)
- [Overview](overview.md)
- [Contract](contract.md)
- [Operation map](operation-map.md)
- [Client reference](reference.md)
- [Consumption](consumption.md)
- [Dependencies](dependencies.md)
- [Business rules](business-rules.md)
- [Tech debt](tech-debt.md)

> **Note:** Statements marked with `*` were inferred from code structure or contextual
> evidence. Statements marked with `**` could not be confirmed; treat as unknown until
> verified.

## Sources
- `Services/SAIF.Services.Web.Proxies/Legacy/DbConnectionsServiceProxy.cs`
- `Services/SAIF.Services.Common/DbConnectionService.cs`
- `Services/SAIF.Services.Web.Proxies/app.config`
