Skip to content

Consumption

A consumer obtains fax delivery by constructing FaxServiceProxy per call from SAIF.Services.WCF.Services.FaxService, which is in turn part of SAIF.Services.Web.Proxies and documented as a consuming library at SAIF.Services.Web.Proxies overview.

Reference style

Field Value
Mechanism Service Reference (svcutil)
Declared in Services/SAIF.Services.Web.Proxies/Service References/Fax/Reference.svcmap
Generated artifacts Services/SAIF.Services.Web.Proxies/Service References/Fax/Reference.cs
Target framework .NET Framework 4.6.2
Regeneration command Visual Studio "Update Service Reference"

Construction

public FaxServiceProxy(string serviceUrl)
{
    Enforce.ArgumentNotNullOrWhiteSpace(serviceUrl, nameof(serviceUrl));
    var binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportCredentialOnly)
    {
        MaxReceivedMessageSize = int.MaxValue,
        MaxBufferSize = int.MaxValue,
        ReaderQuotas = { MaxArrayLength = int.MaxValue }
    };
    binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
    webService = new FaxServiceSoapClient(binding, new EndpointAddress(serviceUrl));
}
Step Requirement
Endpoint address Constructor argument, resolved by FaxService from WcfEnvironmentService.GetConfigSetting(EnvironmentConfigKeys.FaxSoapServiceUrl)
Binding Constructed in code — BasicHttpBinding(TransportCredentialOnly) with Windows client credentials
Credentials Ambient Windows identity of the process, or the impersonated identity if the WCF host impersonates*
Initialization Single-constructor

Endpoint configuration

Setting Value Source Changeable without a rebuild
Endpoint address http://websvcprod/webservices/SAIFFaxService/faxservice.asmx Services/SAIF.Services.WebApi/EnvironmentApi/App_Data/environments.xml:16,35,54,73,91,109 Yes
Binding configuration Constructed in code Services/SAIF.Services.Web.Proxies/FaxServiceProxy.cs:18-28 No
Security mode TransportCredentialOnly FaxServiceProxy.cs:18 No

The app.config <client><endpoint name="FaxServiceSoap"> entry (Services/SAIF.Services.Web.Proxies/app.config:60, address api.saif.com) is present but is not used at runtime, because the wrapper supplies an explicit Binding and EndpointAddress to the generated constructor.

Resilience

Concern Finding Configurable by consumer Source Tech debt
Timeout None configured — binding defaults apply No FaxServiceProxy.cs:18-28 Yes
Retry None configured No — Yes
Circuit breaking None configured No — Yes
Thread safety Not determined from source — — No
Cancellation Not supported — no cancellation on any call site — FaxServiceProxy.cs:43 Yes
Message size limits MaxReceivedMessageSize/MaxBufferSize/MaxArrayLength all set to int.MaxValue Yes FaxServiceProxy.cs:20-22 Yes

The unbounded quotas are copied boilerplate rather than a deliberate choice — the response is empty, so the practical exposure is small, but the setting removes a real safeguard against an oversized response — see Tech debt.

Disposal

Aspect Finding
Disposal performed Close()
Faulted channel handled No — a faulted channel throws from disposal and masks the original failure*
Wrapper responsibility FaxServiceProxy disposes the generated proxy; FaxService.Dispose() disposes the wrapper
Source Services/SAIF.Services.Web.Proxies/FaxServiceProxy.cs:57-65; Services/SAIF.Services.WCF/Services/FaxService.cs:59-67
public void Dispose()
{
    webService.Close();
}

Error handling for consumers

Failure Surfaces as Consumer action
Service unreachable EndpointNotFoundException† None — propagates through FaxService.SendFax to WCF
SOAP fault returned FaultException† None — propagates unchanged
Timeout exceeded TimeoutException† None — propagates unchanged
Response larger than the message size limit Not applicable — the response is empty —
Empty or absent output message Not applicable — Send is one-way —

With multiple recipients, a mid-loop failure at FaxService.SendFax leaves earlier recipients faxed and later ones not, and the caller receives no indication of which; the temp file write to fullFilePath is also not cleaned up when a Send call throws, because the delete happens only after the loop completes.

Usage examples

// Send a fax to each recipient in the request, using a temp copy of the document
foreach (var recipient in config.Recipients)
{
    proxy.SendFax(recipient, fullFilePath);
}
Scenario Operations used Notes
Send one document to multiple fax recipients Send Called once per recipient from FaxService.SendFax

Lifecycle guidance

Question Answer
Construct once or per call Per service instance* — constructed from OperationContext.Current in the FaxService constructor
Disposable Yes (IDisposable)
Safe to share across threads Not determined from source

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.

Sources

  • Services/SAIF.Services.Web.Proxies/FaxServiceProxy.cs
  • Services/SAIF.Services.WCF/Services/FaxService.cs
  • Services/SAIF.Services.Web.Proxies/app.config