---
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 `WCFHost PDFService`† only through the authored `PdfServiceProxy` wrapper, which builds a `BasicHttpBinding` in code and passes a caller-supplied URL to the generated, `internal` `PDFServiceClient`; no repository source constructs `PdfServiceProxy` itself.

## Proxy mechanism

| Aspect | Finding |
| --- | --- |
| Mechanism | Service Reference (svcutil) |
| Proxy type | `PDFServiceClient` (`internal`) |
| Base type | `System.ServiceModel.ClientBase<T>` |
| Contract type | `internal interface IPDFService` |
| Constructed in | `PdfServiceProxy` constructor (`Services/SAIF.Services.Web.Proxies/PDFServiceProxy.cs:14-27`) — the wrapper itself has no in-repository caller |
| Binding configured in | Code — `BasicHttpBinding` built in the wrapper constructor |
| Address supplied by | Constructor argument (`serviceUrl`) passed to `PdfServiceProxy`; the generated `<client><endpoint>` in `app.config` is bypassed |

## Architecture diagram

The construction path below visualizes how a call would reach the remote service if `PdfServiceProxy` were constructed and called.

```mermaid
flowchart TD
    CALLER["Caller of<br>PdfServiceProxy.GetImage<br>(none found in this repository)"] --> WRAP["PdfServiceProxy<br>hand-written wrapper"]
    WRAP --> BIND["BasicHttpBinding<br>built in code, unbounded quotas"]
    BIND --> ADDR["EndpointAddress<br>from caller-supplied serviceUrl"]
    ADDR --> PROXY["PDFServiceClient<br>generated proxy (internal)"]
    PROXY --> REMOTE["WCFHost PDFService<br>remote WCF service"]
    WRAP --> DISPOSE["Close() only<br>on Dispose()"]
```

## Hand-written wrapper

| Field | Value |
| --- | --- |
| **Type** | `PdfServiceProxy` |
| **Source** | `Services/SAIF.Services.Web.Proxies/PDFServiceProxy.cs` |
| **Visibility** | `public` |
| **Implements** | `IDisposable` |
| **Responsibility** | Builds the binding and endpoint address, constructs the generated client, maps caller arguments into `PDFCacheArgs`, invokes `LoadCache`, and returns the cached image bytes |
| **Proxy lifetime** | Per `PdfServiceProxy` instance (constructed in the wrapper's own constructor) |

| Configuration applied | Value | Source |
| --- | --- | --- |
| `BasicHttpBinding` security mode | `None` (default — not set explicitly) | `PDFServiceProxy.cs:20-24` |
| Transport client credential | None configured | `PDFServiceProxy.cs:20-24` |
| `MaxReceivedMessageSize` | `int.MaxValue` | `PDFServiceProxy.cs:22` |
| `MaxBufferSize` | Not set — binding default applies | — |
| Reader quotas (`MaxArrayLength`) | `int.MaxValue` | `PDFServiceProxy.cs:23` |
| Timeouts | None set — binding defaults apply | `PDFServiceProxy.cs:20-24` |

`MaxReceivedMessageSize` and `MaxArrayLength` raised to `int.MaxValue` remove the guard that protects the process from an oversized response; see [Tech debt](tech-debt.md).

## Endpoint resolution

| Environment | Address | Resolved from | Changeable without a rebuild |
| --- | --- | --- | --- |
| All | Unresolved** — the `serviceUrl` constructor argument, supplied by whoever constructs `PdfServiceProxy`; no repository source does so | `PDFServiceProxy.cs:14-27` | Yes — the address is a constructor argument, not a compiled-in literal, so a caller controls it, but no caller exists in this repository to change |

The candidate environment key `legacyPdfServiceUrl` in `environments.xml` points at the same `wcfhost/pdfservice.svc` path across all tracks, but nothing in this repository reads it and passes it to `PdfServiceProxy`*.

## Lifetime and disposal

| Aspect | Finding |
| --- | --- |
| Proxy lifetime | Per `PdfServiceProxy` instance |
| Disposal | `Close()` only — `PDFServiceProxy.cs:59-67` |
| Faulted-channel handling | No `Abort()` path; `Close()` on a faulted channel throws `CommunicationObjectFaultedException` and masks the original failure* |
| Thread safety | Not determined from source |

## Integration points

| System | Type | Purpose |
| --- | --- | --- |
| `WCFHost PDFService`† | SOAP service (WCF) | Loads/caches a document image by sequence number and returns its bytes |

## 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)
- [Tech debt](tech-debt.md)

> **Note:** Statements marked with `†` are derived from dependency library
> documentation via the Legends CLI. 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/PDFServiceProxy.cs`
- `Services/SAIF.Services.Web.Proxies/app.config`
- `Services/SAIF.Services.Web.Proxies/Service References/PDFService/Reference.cs`
- `Services/SAIF.Services.WebApi/EnvironmentApi/App_Data/environments.xml`
