Skip to content

SAIF.Services.Web.Proxies architecture

SAIF.Services.Web.Proxies is the outbound-integration (anti-corruption) layer for SAIF.Services and its sibling hosts: it hosts 12 generated SOAP/WCF service-reference proxies (11 authored here plus CleanAddressSvc in SAIF.Services) behind a small number of intention-revealing wrapper classes, each of which hides an internal generated client, maps SAIF.Core contract types to and from wire types, and constructs its own binding and endpoint in code rather than relying on app.config.

Responsibilities

  • Wrap 8 authored SOAP proxies (ActiveDirectory, Document, Fax, Logging, PDFService, WorkCalendar, DbConnection, SimpleCertifiedMail) so that consumers depend on a small typed API instead of the generated ClientBase<T>/DuplexClientBase<T> surface.
  • Map SAIF.Core contract DTOs (Contact, Address, PhoneNumber, PersonName, ApplicationExceptionDetail, CertifiedLabelData, DistanceResults, FaxInfoClass, FaxRecipient, DocumentGenerationConfig, DeferredPrintConfig, PrintConfig) to and from each proxy's wire types.
  • Resolve outbound service endpoints, either from a caller-supplied serviceUrl (7 wrappers) or from IEnvironmentService.GetConfigSetting (SimpleCertifiedMailServiceProxy, GoogleMapsApiServiceProxy).
  • Provide one non-SOAP, hand-rolled REST/XML client, GoogleMapsApiServiceProxy, for the Google Distance Matrix API over System.Net.WebRequest.
  • Implement IDisposable on every wrapper to close the underlying generated client.

Component boundaries

  • ActiveDirectoryServiceProxy, DocumentServiceProxy, FaxServiceProxy, LoggingServiceProxy, PdfServiceProxy, WorkCalendarServiceProxy, Legacy.DbConnectionServiceProxy: seven uniform SOAP wrappers, each taking serviceUrl in its constructor and delegating one-to-one to wire operations.
  • SimpleCertifiedMailServiceProxy / ISimpleCertifiedMailServiceProxy: a constructor-injected (IEnvironmentService, ILogService) wrapper around the third-party SimpleCertifiedMail ADS SOAP service, with its own configuration resolution and error logging.
  • GoogleMapsApiServiceProxy / IGoogleMapsApiServiceProxy: a constructor-injected REST/XML client for the Google Distance Matrix API; the only wrapper that is not SOAP.
  • Helpers / Extensions (internal): shared mapping utilities, including MapEnumByName (used by DocumentServiceProxy) and ToErrorInfoStruct (used by LoggingServiceProxy).
  • 11 generated Service References/<Name>/Reference.cs clients (ActiveDirectory, CallRex, CallRexState, DbConnection, Document, Fax, Logging, PDFService, SimpleCertifiedMail, SMTP, WorkCalendar): the wire-level ClientBase<T>/DuplexClientBase<T> proxies, each documented separately (see Related documentation).
  • CallRex and CallRexState generated clients are public in the packaged assembly but have no authored wrapper and no in-repo caller; the generated SMTP client (clsSAIFMessageSoapClient) is internal and also has no authored wrapper.

Interaction model

  • All eight authored SOAP wrappers follow the same construction pattern: guard serviceUrl (and other required arguments) with Enforce, build an in-code Binding plus EndpointAddress(serviceUrl) that bypasses the <system.serviceModel><client> endpoints declared in app.config, delegate one-to-one to the wire operation, and implement Dispose() by calling webService.Close() without an Abort() fallback on the fault path.
  • Endpoint resolution is split between callers and this library: DocumentServiceProxy and Legacy.DbConnectionServiceProxy receive their URL from the caller's own configuration key (documentGeneratorServiceUrl, dbconnectionserviceurl), while SimpleCertifiedMailServiceProxy and GoogleMapsApiServiceProxy resolve their own URL/API key via IEnvironmentService.GetConfigSetting.
  • Binding security varies per wrapper: Windows-integrated TransportCredentialOnly for FaxServiceProxy; HTTPS Transport security for SimpleCertifiedMailServiceProxy; plain, unsecured BasicHttpBinding for ActiveDirectoryServiceProxy, LoggingServiceProxy, WorkCalendarServiceProxy, Legacy.DbConnectionServiceProxy, DocumentServiceProxy, and PdfServiceProxy.
  • ISimpleCertifiedMailServiceProxy and IGoogleMapsApiServiceProxy are constructor-injected into SAIF.Services consumers (SubpoenaLabelService, DocumentDeferredService, SubpoenaService); no Autofac registration for either interface exists anywhere in this repository, so the composition root is external**.
  • This library registers no services of its own and performs no persistence; database interaction is limited to Legacy.DbConnectionServiceProxy resolving Oracle/SQL Server connection strings remotely, through the DbConnection SOAP proxy, without executing any SQL itself.

Architecture diagram

The following diagram shows how SAIF.Services and other hosts consume the authored wrappers, which in turn drive the generated SOAP/WCF and REST clients hosted in this library.

flowchart TD
    Consumer["SAIF.Services / SAIF.Services.Common /<br>SAIF.Services.WCF (callers)"] --> Wrappers["Authored *ServiceProxy wrappers<br>(this library)"]
    Wrappers --> Generated["Generated SOAP/WCF clients<br>(Service References/*)"]
    Wrappers --> GoogleRest["GoogleMapsApiServiceProxy<br>(REST/XML over WebRequest)"]
    Generated --> External["11 consumed SOAP services<br>(ActiveDirectory, Document, Fax,<br>Logging, PDFService, WorkCalendar,<br>DbConnection, SimpleCertifiedMail,<br>CallRex, CallRexState, SMTP)"]
    GoogleRest --> GoogleApi["Google Distance Matrix API"]

Sequence diagram

The following diagram shows the typical wrapper call sequence, using the certified-label request as a representative example.

sequenceDiagram
    participant Client as SAIF.Services consumer
    participant Proxy as SimpleCertifiedMailServiceProxy
    participant Env as IEnvironmentService
    participant Wire as ADSAPISoapClient (generated)
    Client->>Proxy: GetLabelOnly(certifiedLabelData)
    Proxy->>Env: GetConfigSetting(credential keys, as fallback)
    Proxy->>Wire: getCertifiedLabel(request)
    Wire-->>Proxy: label response (StatusCode, LabelImage)
    Proxy-->>Client: label image, or thrown SimpleCertifiedException

Design constraints

  • Every authored wrapper builds its own Binding and EndpointAddress in code, which means the 15 <client> endpoints and 16 binding configurations declared in app.config are inert design-time residue; a class library's app.config is also not loaded by consuming hosts*.
  • Dispose() calls Close() without Abort() on a faulted channel, a known WCF anti-pattern that can throw from Dispose on a faulted proxy*.
  • No wrapper configures explicit SOAP send/receive timeouts (WCF defaults apply), except GoogleMapsApiServiceProxy, which sets a 5000 ms WebRequest.Timeout; only PdfServiceProxy.GetImage implements retry behavior, and it delegates the actual wait/retry to the remote PDF service via PDFCacheArgs.
  • Legacy.DbConnectionServiceProxy requests and returns Oracle/SQL Server connection strings, which contain credentials, over a default unsecured BasicHttpBinding; whether the transport is HTTPS depends only on the URL scheme the caller supplies.
  • Three configuration values read by this library are secrets or credentials (SimpleCertifiedMailService.Password, SimpleCertifiedMailService.PartnerKey, googlemaps.apikey) but are read with the non-secure IEnvironmentService.GetConfigSetting rather than GetSecureConfigSetting (see Configuration).
  • Several referenced NuGet packages (SAIF.Web.API.Clients, SAIF.HashUtil, Autofac, FluentValidation, log4net, Newtonsoft.Json, RestSharp) and the third-party CallRex.Utilities.dll/CallrexAPIUtilities.dll binaries have no authored usage in this library; it is unknown whether they are required transitively or are stale**.

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

  • Services/SAIF.Services.Web.Proxies/SAIF.Services.Web.Proxies.csproj
  • Services/SAIF.Services.Web.Proxies/ActiveDirectoryServiceProxy.cs
  • Services/SAIF.Services.Web.Proxies/DocumentServiceProxy.cs
  • Services/SAIF.Services.Web.Proxies/FaxServiceProxy.cs
  • Services/SAIF.Services.Web.Proxies/GoogleMapsApiServiceProxy.cs
  • Services/SAIF.Services.Web.Proxies/Helpers.cs
  • Services/SAIF.Services.Web.Proxies/ISimpleCertifiedMailServiceProxy.cs
  • Services/SAIF.Services.Web.Proxies/LoggingServiceProxy.cs
  • Services/SAIF.Services.Web.Proxies/PDFServiceProxy.cs
  • Services/SAIF.Services.Web.Proxies/SimpleCertifiedMailServiceProxy.cs
  • Services/SAIF.Services.Web.Proxies/WorkCalendarServiceProxy.cs
  • Services/SAIF.Services.Web.Proxies/Legacy/DbConnectionsServiceProxy.cs
  • Services/SAIF.Services.Web.Proxies/app.config