Smp.Core.Encompass
2.0.2
See the version list below for details.
dotnet add package Smp.Core.Encompass --version 2.0.2
NuGet\Install-Package Smp.Core.Encompass -Version 2.0.2
<PackageReference Include="Smp.Core.Encompass" Version="2.0.2" />
<PackageVersion Include="Smp.Core.Encompass" Version="2.0.2" />
<PackageReference Include="Smp.Core.Encompass" />
paket add Smp.Core.Encompass --version 2.0.2
#r "nuget: Smp.Core.Encompass, 2.0.2"
#:package Smp.Core.Encompass@2.0.2
#addin nuget:?package=Smp.Core.Encompass&version=2.0.2
#tool nuget:?package=Smp.Core.Encompass&version=2.0.2
Smp.Core.Encompass
A .NET client library for the Encompass API by ICE Mortgage Technology. Provides strongly-typed access to loan data, pipeline queries, document management, user administration, and more with built-in OAuth2 authentication, token caching, rate limiting, and automatic retry on 401 responses.
Installation
Install via NuGet:
dotnet add package Smp.Core.Encompass
Quick Start
1. Configure
Add an Encompass section to your appsettings.json:
{
"Encompass": {
"Username": "api_user",
"Password": "your_password",
"InstanceId": "BE11200822",
"ClientId": "your_client_id",
"ClientSecret": "your_client_secret",
"TokenLifetime": "00:50:00",
"RateLimit": {
"TokenLimit": 20,
"ReplenishmentPeriod": "00:00:01",
"TokensPerPeriod": 20,
"QueueLimit": 100
}
}
}
2. Register Services
Choose one of the registration patterns below based on your configuration needs.
Default Configuration (Configuration Section)
Use this pattern when all settings are in your configuration file:
builder.Services.AddEncompassClient();
Custom Configuration Section
Use this pattern if your Encompass configuration is under a different section path:
// For configuration at "Services:Encompass"
builder.Services.AddEncompassClient("Services:Encompass");
Inline/Programmatic Configuration
Use this pattern for fully programmatic configuration, useful in testing:
builder.Services.AddEncompassClient(options =>
{
options.Username = Environment.GetEnvironmentVariable("ENCOMPASS_USERNAME")!;
options.Password = Environment.GetEnvironmentVariable("ENCOMPASS_PASSWORD")!;
options.InstanceId = "BE11200822";
options.ClientId = Environment.GetEnvironmentVariable("ENCOMPASS_CLIENT_ID")!;
options.ClientSecret = Environment.GetEnvironmentVariable("ENCOMPASS_CLIENT_SECRET")!;
});
Hybrid Configuration (Configuration + Override)
Use this pattern when you want to bind most settings from configuration but override sensitive values from secure sources like Azure Key Vault:
// appsettings.json has: Username, InstanceId, ClientId
builder.Services.AddEncompassClient("Encompass", async options =>
{
// Override sensitive values from Key Vault
var keyVaultUri = new Uri(builder.Configuration["KeyVault:Uri"]!);
var credential = new DefaultAzureCredential();
var client = new SecretClient(keyVaultUri, credential);
options.Password = (await client.GetSecretAsync("EncompassPassword")).Value.Value;
options.ClientSecret = (await client.GetSecretAsync("EncompassClientSecret")).Value.Value;
});
Custom HttpClient Configuration
Use this pattern to customize the underlying HttpClient (timeouts, headers, etc.):
builder.Services.AddEncompassClient(httpClient =>
{
httpClient.Timeout = TimeSpan.FromSeconds(60);
httpClient.DefaultRequestHeaders.Add("User-Agent", "MyApp/1.0");
});
3. Use the Client
Inject IEncompassClient into your services:
public class LoanService(IEncompassClient encompassClient)
{
public async Task<string> GetLoanAsync(string loanGuid)
{
return await encompassClient.Loans.GetLoanRawAsync(loanGuid);
}
}
API Reference
The EncompassClient exposes the following sub-clients:
Loans
Read and write loan data, field values, and disclosure tracking logs.
// Get raw loan JSON
string loanJson = await client.Loans.GetLoanRawAsync(loanGuid);
// Read specific fields
var fields = await client.Loans.FieldReaderAsync(loanGuid, ["4000", "1109"]);
// Write field values
await client.Loans.FieldWriterAsync(loanGuid, [
new FieldValue { Id = "CX.CUSTOM.FIELD", Value = "NewValue" }
]);
// Get disclosure tracking logs
var logs = await client.Loans.GetDisclosureTrackingLogsAsync(loanGuid);
// Get loan associates
string associates = await client.Loans.GetLoanAssociatesRawAsync(loanGuid);
Loan Pipeline
Query and search the loan pipeline with filters, field selection, and pagination.
// Find a loan GUID by loan number
string guid = await client.LoanPipeline.FindLoanGuidByLoanNumberAsync("1234567890");
// Query the pipeline with filters
var items = await client.LoanPipeline.GetAllPipelineItemsAsync(new LoanPipelineQuery
{
Fields = ["Loan.LoanNumber", "Loan.BorrowerName"],
Filter = new Filter
{
Operator = "and",
Terms =
[
new Filter { CanonicalName = "Loan.LoanFolder", Value = "My Pipeline", MatchType = "Exact" },
new Filter { CanonicalName = "Loan.DateCreated", Value = "2024-01-01", MatchType = "GreaterThan" }
]
}
});
// Paginated access
var page = await client.LoanPipeline.GetPipelinePageAsync(new LoanPipelineRequest
{
LoanPipelineQuery = query,
Start = 0
});
Documents
Retrieve loan document stacking order using Encompass stacking templates.
var stackingDocs = await client.Documents.GetLoanStackingDocumentsAsync(
new LoanStackingDocumentsRequest
{
Loan = new Entity { EntityId = loanGuid, EntityType = "urn:elli:encompass:loan" },
StackingTemplate = new Entity { EntityId = templateId }
});
// Get all attachment IDs from the stacking order
var attachmentIds = stackingDocs.GetAttachmentIds();
Export Jobs
Create, monitor, and download eFolder export jobs.
// Create an export job
var job = await client.ExportJobs.CreateExportJobAsync(new ExportJobRequest
{
Source = new Entity { EntityId = loanGuid, EntityType = "urn:elli:encompass:loan" },
Entities = attachmentIds.Select(id => new Entity { EntityId = id }).ToList()
});
// Check status
var status = await client.ExportJobs.GetExportJobStatusAsync(job.JobId!);
// Download the file
using var stream = await client.ExportJobs.DownloadExportJobAsync(job.JobId!);
Users
Query and retrieve Encompass user accounts.
// Get all users
var allUsers = await client.Users.GetAllUsersAsync();
// Get a single user
var user = await client.Users.GetUserAsync("userId");
// Get multiple users by ID
var users = await client.Users.GetUsersByIdsAsync(["user1", "user2"]);
// Paginated access
var page = await client.Users.GetUsersPageAsync(start: 0, limit: 50);
Custom Data Objects
Manage custom data objects (CDOs) at the company, user, or loan level.
// List CDO names
var names = await client.CustomDataObjects.GetCustomDataObjectListAsync(CustomDataObjectTypes.Company);
// Get a CDO
var cdo = await client.CustomDataObjects.GetCustomDataObjectAsync(
CustomDataObjectTypes.Loans, "MyCdo", entityId: loanGuid);
// Upsert a CDO from an object (auto-serialized to JSON and Base64-encoded)
await client.CustomDataObjects.UpsertCustomDataObjectAsync(
CustomDataObjectTypes.Loans, "MyCdo", myObject, entityId: loanGuid);
// Delete a CDO
await client.CustomDataObjects.DeleteCustomDataObjectAsync(
CustomDataObjectTypes.Company, "OldCdo");
Loan Batch Update
Apply field updates to multiple loans in a single batch operation.
// Batch update by loan GUIDs
var jobId = await client.LoanBatchUpdate.CreateBatchUpdateJobAsync(
new LoanBatchUpdateRequest(
loanGuids: ["guid1", "guid2"],
jsonLoanData: """{"applications":[{"borrower":{"fullName":"Test"}}]}"""));
// Check batch update status
var status = await client.LoanBatchUpdate.GetBatchUpdateJobStatusAsync(jobId);
Settings
Retrieve Encompass system settings.
// Get all document stacking templates
var templates = await client.Settings.GetAllDocumentStackingTemplatesAsync();
// Get all eFolder document definitions
var docs = await client.Settings.GetAllEFolderDocumentsAsync();
Resource Locks
Manage exclusive locks on loans for safe concurrent access.
// Lock a loan
var resourceLock = await client.ResourceLocks.LockLoanAsync(loanGuid);
// Unlock by lock ID
await client.ResourceLocks.UnlockLoanAsync(resourceLock.Id!, loanGuid);
// Or unlock all locks on a loan
await client.ResourceLocks.UnlockLoanAsync(loanGuid);
// Check active locks
var locks = await client.ResourceLocks.GetResourceLocksAsync(loanGuid);
Configuration Options
EncompassClientOptions
| Property | Required | Default | Description |
|---|---|---|---|
Username |
Yes | - | Encompass user account username |
Password |
Yes | - | Encompass user account password |
InstanceId |
Yes | - | Encompass instance identifier |
ClientId |
Yes | - | OAuth2 client ID |
ClientSecret |
Yes | - | OAuth2 client secret |
TokenLifetime |
No | 00:50:00 |
Token refresh interval (Encompass tokens expire at 60 min) |
RateLimit |
No | Enabled | Rate limit configuration, set to null to disable |
RateLimitOptions
Uses a token bucket algorithm for client-side rate limiting.
| Property | Default | Description |
|---|---|---|
TokenLimit |
20 |
Maximum burst capacity |
ReplenishmentPeriod |
00:00:01 |
How often permits are added |
TokensPerPeriod |
20 |
Permits added per period |
QueueLimit |
100 |
Maximum queued requests |
Key Features
- OAuth2 Authentication - Automatic token acquisition, caching, and refresh with thread-safe semaphore protection
- Automatic 401 Retry - Transparently refreshes expired tokens and retries failed requests
- Rate Limiting - Built-in token bucket rate limiter to stay within API call limits
- Pagination - Automatic iteration through all pages with
GetAll*Asyncmethods, or manual control withGet*PageAsyncmethods - Dependency Injection - Single-line registration via
AddEncompassClient()with options validation on startup
Requirements
- .NET 10.0+
Testing & Mocking
The library interfaces support dependency injection, making it easy to mock in unit tests:
Testing with Moq
using Moq;
using Xunit;
[Fact]
public async Task GetLoanAsync_WithMockedClient_ReturnsExpectedJson()
{
// Arrange
var mockEncompassClient = new Mock<IEncompassClient>();
var mockLoans = new Mock<ILoans>();
var expectedJson = """{"loanNumber":"123456","borrowerName":"John Doe"}""";
mockLoans.Setup(l => l.GetLoanRawAsync("test-guid", null, default))
.ReturnsAsync(expectedJson);
mockEncompassClient.Setup(c => c.Loans).Returns(mockLoans.Object);
var loanService = new LoanService(mockEncompassClient.Object);
// Act
var result = await loanService.GetLoanAsync("test-guid");
// Assert
Assert.Equal(expectedJson, result);
mockLoans.Verify(l => l.GetLoanRawAsync("test-guid", null, default), Times.Once);
}
Testing with NSubstitute
using NSubstitute;
using Xunit;
[Fact]
public async Task GetUserAsync_WithMockedClient_ReturnsExpectedUser()
{
// Arrange
var mockEncompassClient = Substitute.For<IEncompassClient>();
var mockUsers = Substitute.For<IUsers>();
var expectedUser = new User { Id = "user123", Name = "Jane Smith" };
mockUsers.GetUserAsync("user123", default).Returns(Task.FromResult(expectedUser));
mockEncompassClient.Users.Returns(mockUsers);
var userService = new UserService(mockEncompassClient);
// Act
var result = await userService.GetUserAsync("user123");
// Assert
Assert.Equal(expectedUser.Id, result.Id);
await mockUsers.Received(1).GetUserAsync("user123", default);
}
Injecting Mocks in Dependency Injection
using Microsoft.Extensions.DependencyInjection;
using Moq;
[Fact]
public async Task Service_WithMockedDependencies()
{
// Arrange
var services = new ServiceCollection();
var mockEncompassClient = new Mock<IEncompassClient>();
mockEncompassClient.Setup(c => c.LoanPipeline.FindLoanGuidByLoanNumberAsync("1234567890", default))
.ReturnsAsync("loan-guid-123");
services.AddScoped(_ => mockEncompassClient.Object);
services.AddScoped<ILoanService, LoanService>();
var provider = services.BuildServiceProvider();
var loanService = provider.GetRequiredService<ILoanService>();
// Act
var result = await loanService.FindLoanAsync("1234567890");
// Assert
Assert.NotNull(result);
}
Interface Contracts
All sub-clients are accessible through their respective interfaces:
IAuthenticationClient- Token managementILoans- Loan data and field operationsILoanPipeline- Pipeline querying and searchIDocuments- Document stackingIExportJobs- eFolder exportsIUsers- User queriesICustomDataObjects- CDO managementILoanBatchUpdate- Batch operationsISettings- System settings retrievalIResourceLocks- Loan locking mechanisms
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.Extensions.Configuration.Abstractions (>= 10.0.5)
- Microsoft.Extensions.Configuration.Binder (>= 10.0.5)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.5)
- Microsoft.Extensions.Http (>= 10.0.5)
- Microsoft.Extensions.Options (>= 10.0.5)
- Microsoft.Extensions.Options.DataAnnotations (>= 10.0.5)
- System.Threading.RateLimiting (>= 10.0.5)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.