---
title: CertificateHolderService
summary: API reference for CertificateHolderService.
status: draft
owner: SAIF Doc Gen
last_reviewed: 2026-09-24
library: SAIF.Services
reference_type: package
---

# CertificateHolderService

Implements `ICertificateHolderService`, providing CRUD-style lifecycle operations (add, save, expire, reinstate, supersede) and search/lookup for certificate holders by loading and mutating the domain `certDomain.CertificateHolder` type (via `IUnitOfWork`) and mapping it to the `CertificateHolder` DTO with AutoMapper, using `IValidationService` to validate edits and `IUserProfileService` to attribute changes to the current user.

## Purpose
- Retrieves a single certificate holder by ID, or a filtered/searchable list of certificate holders for a policy.
- Adds, saves (updates), expires, reinstates, and supersedes certificate holders as transactional domain operations.
- Validates `CertificateHolderEdit` input via `IValidationService` before any add/save/supersede operation, throwing `SaifValidationException` on failure.
- Maps between the `certData.CertificateHolder` persistence type and the `CertificateHolder`/`Address` service DTOs, including phone/fax number and address-field normalization.

## Context
- Namespace: `SAIF.Services.Policies.Certificates`
- Assembly/package: `SAIF.Services` (packaged inside the `SAIF.SAIFCode.Core` NuGet package).

## Public members
| Member | Signature | Purpose |
| --- | --- | --- |
| CertificateHolderService (constructor) | `public CertificateHolderService(IUnitOfWork unitOfWork, IValidationService validationService, IUserProfileService userProfileService)` | Wires the unit of work, validation service, and user-profile service (all null-checked via `Enforce.ArgumentNotNull`) used by every operation on this type. |
| GetCertificateHolder | `public CertificateHolder GetCertificateHolder(long certificateHolderId)` | Loads the domain certificate holder for the given ID and maps it to a `CertificateHolder` DTO, throwing `CertificateHolderServiceException` if no matching data exists. |
| GetCertificateHolders (with search term) | `public IEnumerable<CertificateHolder> GetCertificateHolders(long policyNumber, bool includeExpired, string searchTerm)` | Queries certificate holders for a policy via a locally constructed `CertificateHolderQueryProvider`, optionally including expired ones and filtering by the supplied search term, then maps the results to `CertificateHolder` DTOs. |
| GetCertificateHolders (no search term) | `public IEnumerable<CertificateHolder> GetCertificateHolders(long policyNumber, bool includeExpired)` | Queries all (or only active) certificate holders for a policy via a locally constructed `CertificateHolderQueryProvider` and maps the results to `CertificateHolder` DTOs. |
| AddCertificateHolder | `public long AddCertificateHolder(CertificateHolderEdit certificateHolderEdit)` | Validates the edit DTO, then creates a new domain certificate holder for the current user inside a transaction and returns its generated ID. |
| SaveCertificateHolder | `public void SaveCertificateHolder(long id, CertificateHolderEdit certificateHolderEdit)` | Validates the edit DTO, then updates the existing domain certificate holder identified by `id` for the current user inside a transaction. |
| ExpireCertificateHolder | `public void ExpireCertificateHolder(long certificateHolderId)` | Loads the domain certificate holder and calls its `Expire()` behavior inside a transaction, marking it expired. |
| ReinstateCertificateHolder | `public void ReinstateCertificateHolder(long certificateHolderId)` | Loads the domain certificate holder and calls its `Reinstate()` behavior inside a transaction, reversing an expiration. |
| SupersedeCertificateHolder | `public long SupersedeCertificateHolder(long originalCertificateHolderId, CertificateHolderEdit newCertificateHolderEdit)` | Validates the new edit DTO, loads the original certificate holder (throwing `CertificateHolderServiceException` if not found), creates the replacement certificate holder, calls `Supersede` on the original to link the two, commits the transaction, and returns the new certificate holder's ID. |

## Behavioral notes
- A static constructor registers AutoMapper mappings from `certData.CertificateHolder` to both `Address` and `CertificateHolder`, normalizing null city/state/address-line/plus-four-code fields to empty strings, mapping phone/fax to `PhoneNumber` instances, and copying the `IsForeign` flag onto both after mapping; this runs once per process.
- `AddCertificateHolder`, `SaveCertificateHolder`, `ExpireCertificateHolder`, `ReinstateCertificateHolder`, and `SupersedeCertificateHolder` all wrap their domain mutation in `unitOfWork.Begin()`/`unitOfWork.Commit()`.
- `ValidateCertificateHolderEdit` throws `SaifValidationException` (carrying the validation result) when `IValidationService.Validate` reports the edit invalid, before any transaction is opened.
- `CurrentUser()` lazily resolves and caches the acting user via `IUserProfileService.GetCurrentUser()` for the lifetime of the service instance.
- `GetCertificateHolders` and `GetCertificateHolder`/`SupersedeCertificateHolder` construct domain/query-provider objects (`certDomain.CertificateHolder`, `CertificateHolderQueryProvider`) directly per call rather than through injected abstractions, coupling these methods to concrete types.*

## Constraints and usage notes
- Only the three constructor parameters are null-checked; edit DTOs passed to individual methods are validated via `IValidationService`, not via null checks.*
- `GetCertificateHolder` and the original-holder lookup inside `SupersedeCertificateHolder` both throw `CertificateHolderServiceException` when the underlying domain data is null, so callers must be prepared to catch this exception for not-found scenarios rather than receiving a null/empty result.

> **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/Policies/Certificates/CertificateHolderService.cs`
