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

# UserExtractService

Implements `IUserExtractService`, synchronizing cached application-access flags (PolicyCenter, BillingCenter, ContactManager) for extracted system users and producing an XML export of users who have changed since their last extract, resolving each user's name/contact details from the ADP employee feed, WCIS employee data, or legacy system-user records. It depends on `IUnitOfWork` for `SystemUserRef`/`SystemUser`/`WcisEmployee`/`AdpEmployeeFeed` repository access and `IUserProfileService` to check each user's authorization against PolicyCenter/BillingCenter/ContactManager.

## Purpose
- Refreshes each tracked system user's PolicyCenter/BillingCenter/ContactManager access flags from the current authorization service, persisting only the users whose access actually changed.
- Selects system users who are new or updated since their last extract, resolves their profile details from ADP, WCIS, or legacy system-user data, and writes them to an XML export file.
- Logs which data source (system user, WCIS, ADP, or "not found") was used for each extracted user via the supplied control log.

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

## Public members
| Member | Signature | Purpose |
| --- | --- | --- |
| UserExtractService(...) | `public UserExtractService(IUnitOfWork unitOfWork, IUserProfileService userProfileService)` | Validates both collaborators are non-null via `Enforce.ArgumentNotNull` and wires them in. |
| UpdateUserAccess | `public long UpdateUserAccess()` | Within a transaction, re-checks each tracked user's PolicyCenter/BillingCenter/ContactManager authorization and updates the stored flags (stamping update user `"GWI0001U"`) only when at least one flag differs from the current value; returns the count of users updated. |
| ExtractUsers | `public long ExtractUsers(string fullFileName, ILogWriter controlLog)` | Within a transaction, selects users updated since their last extract (or updated with at least one access flag set and never previously extracted), resolves each one's profile fields from ADP/WCIS/system-user data, writes the resulting user list as XML to `fullFileName`, stamps each included user's extract/update date and user (`"GWI0001X"`), and returns the number of users written; throws `ArgumentNullException` if `controlLog` is null. |

## Behavioral notes
- `ExtractUsers` inclusion logic is a compound rule: a user is included if it has been updated since its last extract, or if it has never been extracted but has an update date and at least one access flag set; users failing both conditions are skipped entirely.
- Profile resolution follows a strict source order: users without an `EmployeeId` are resolved from `SystemUser` records first, falling back to `WcisEmployee` (marked inactive if neither is found); users with an `EmployeeId` are resolved from `AdpEmployeeFeed` only, and are dropped from the export entirely if no matching ADP record exists.
- The generated XML has a fixed string manipulation applied (`Replace("utf-16","utf-8")` and removing a 117-character slice at offset 39) to strip an unwanted node from the serialized `ExtractedUsers` document before writing it to disk*.
- Update-user stamps use fixed system account identifiers (`"GWI0001U"` for access updates, `"GWI0001X"` for extraction) rather than the injected `IUserProfileService`'s current user.

> **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/SystemUsers/UserExtractService.cs
