Example: .NET console app dependencies¶
Doc gen writes docs/applications/<app-slug>/dependencies.md once per console
application to record the libraries, packages, APIs, and databases a run depends
on. Reviewers cross-check it against the project file, packages.config, and
RegisterAppDependencies, because a wrong Reference Type changes how the portal
links the application to the libraries it consumes.
What reviewers should check¶
SAIF.Framework.Windowsappears in Internal dependencies as aNuGet Packagewith no project path. Recording it as aProject Referenceis a defect even when the surrounding description is right.- Reference Type is exactly one of
Project Reference,NuGet Package, orNuGet Package (same-repo); values such as "Framework" or "Shared" are wrong. - Sections appear in template order — Internal, External, Transitive, API, Database connections, Dependency risks and notes, Related documentation, Sources — and a conditional section with no rows is omitted entirely rather than filled with "None".
- Transitive rows exclude BCL and
System.*packages, name the source framework by its canonical dotted library name rather than a folder slug, and carry†. The framework types reached throughSAIF.Framework.Windowsbelong here, not in the internal table. - The API dependencies table names concrete endpoints, the class that calls them, and the config key the base URL comes from, and those endpoints match the client package's documented surface.
- Database connections list one row per
DatabaseConfigregistered inRegisterAppDependencies, with the config name matching the Autofac registration name used to resolveIUnitOfWork. - Every dependency table ends with a
Usagecolumn that says how this application uses the dependency, not what the package does in general.
Example¶
The document below is a complete, correct console-dependencies.md for a
fictional .NET Framework console application.
View rendered example — the same document as a real page, so you can compare rendering as well as source.
---
title: Dependencies
summary: Internal libraries, external packages, framework components, API endpoints, and database connections.
status: draft
owner: Policy Systems Team
last_reviewed: 2026-09-10
---
# Dependencies
`SAIF.Policy.RenewalNotice` has a small, entirely package-based dependency
surface: there are no project references in the repository. It takes two
internal NuGet packages — `SAIF.Framework.Windows` for the console lifecycle and
`SAIF.Agency.Api.Client` for agency and agent lookups — and picks up the rest of
the SAIF framework transitively through them. Externally it depends on the Oracle
managed driver, NHibernate, Autofac, and the usual JSON and logging packages. All
persistence is against a single Oracle database registered as `policyDb`, and the
only outbound HTTP calls are to `SAIF.Agency.Api`.
## Internal dependencies
| Dependency | Reference Type | Project path | Usage |
| --- | --- | --- | --- |
| `SAIF.Framework.Windows` | NuGet Package | — | Console application framework: runner, argument container, and lifecycle base classes |
| `SAIF.Agency.Api.Client` | NuGet Package | — | Supplies `AgencyClient`/`IAgencyClient`; `GetAgency` and `GetAgentsForAgency` resolve the agency and appointed servicing agent printed on each notice. |
## External dependencies
| Dependency | Version | Usage |
| --- | --- | --- |
| Oracle.ManagedDataAccess | 21.11.0 | Managed Oracle driver behind the `policyDb` NHibernate session factory. |
| NHibernate | 5.3.13 | Maps `PolicyTerm`, `RenewalNotice`, `RenewalNoticeQueueItem`, and `NoticeTemplate`, and provides the unit of work the notice transaction commits through. |
| Autofac | 6.5.0 | Container built in `RegisterAppDependencies`; resolves `RenewalNoticeApplication` and its services. |
| Newtonsoft.Json | 13.0.3 | Serializes the agency and agent payloads exchanged with `SAIF.Agency.Api` and the notice merge model handed to the template renderer. |
| log4net | 2.0.15 | Writes the application log configured in `App.config` alongside the `file0`-`file2` destinations. |
| System.Configuration | 4.0.0.0 | Reads `ApplicationHost`, `ApplicationName`, `AgencyApiTimeoutSeconds`, and `PrintFileExtension` from `App.config`. |
| System.Net.Mail | 4.0.0.0 | Sends the run summary mail from `Finish` to `renewalnotice.notificationRecipients`. |
## Transitive dependencies
Dependencies in this section are inherited from framework packages — for a console application on `SAIF.Framework.Windows` this includes `SAIF.Framework.Common`, `SAIF.Framework.Data.NHibernate`, `SAIF.HashUtil`, and `SAIF.Web.API.Clients`. They are not directly referenced by this application but are required at runtime.
| Dependency | Source framework | Type | Usage |
| --- | --- | --- | --- |
| `IConsoleLogService` | `SAIF.Framework.Common` | Transitive | Console and file logging surface injected into `ConsoleBase`† |
| `IUnitOfWork` | `SAIF.Framework.Data.NHibernate` | Transitive | NHibernate unit of work resolved from the container† |
| `IEnvironmentService` | `SAIF.Framework.Core` | Transitive | Environment API configuration retrieval† |
| `SaifConsoleException` | `SAIF.Framework.Windows` | Transitive | Exception hierarchy that maps `DatabaseErrorException`, `DataErrorException`, `FileInputOutputException`, and `NoDataFoundException` to exit codes 2, 3, 4, and 6.† |
| `SaifStandardCommandLineParser` | `SAIF.Framework.Windows` | Transitive | Parses the named arguments and echoes each resolved value before `Initialize` runs.† |
| `SAIF.HashUtil` | `SAIF.Framework.Common` | Transitive | Produces the notice document hash stored on `POLICY.RENEWAL_NOTICE` so a regenerated notice can be compared to the queued one.† |
| `JsonHttpClient` | `SAIF.Web.API.Clients` | Transitive | HTTP surface underneath `AgencyClient`: request composition, the API key header, timeout enforcement, and the result envelope.† |
## API dependencies
| Endpoint | Method | Called from | Base URL config key | Usage |
| --- | --- | --- | --- | --- |
| `v1/agencies/{agencyNumber}` | GET | `AgentResolver` (`GetAgency`) | `agency.api.baseUrl` | Resolves the agency name and mailing address printed in the notice footer, and serves as the `Initialize` health probe for the agency number in `renewalnotice.healthProbeAgencyNumber`. |
| `v1/agencies/{agencyNumber}/agents` | GET | `AgentResolver` (`GetAgentsForAgency`) | `agency.api.baseUrl` | Returns the agents appointed at the agency; the appointed servicing agent for the policy term is selected from this list and printed as the contact. |
## Database connections
| Database | Config name | Schema/User | Access method | Usage |
| --- | --- | --- | --- | --- |
| Policy (Oracle) | `policyDb` | `POLICY` schema, `POLICY_APP` user | NHibernate `IUnitOfWork` | Reads eligible terms from `POLICY.POLICY_TERM` and the template from `POLICY.NOTICE_TEMPLATE`; inserts `POLICY.RENEWAL_NOTICE` and `POLICY.RENEWAL_NOTICE_QUEUE` rows in the per-notice transaction. |
## Dependency risks and notes
- `SAIF.Framework.Windows` is consumed as a NuGet package, so the argument
parser, the exit-code mapping, and the header and footer output change only
when the package version is bumped and the application is redeployed. The exit
codes the operational runbook documents come from that package, not from
`Program.cs`.
- `SAIF.Agency.Api.Client` 3.2.0 is compiled against the `v1` routes of
`SAIF.Agency.Api`. A breaking change on the API side surfaces here as skipped
notices rather than a failed run, because agent resolution failures are
per-term recoverable errors — the failure count in the run summary is the only
signal.
- The agency client is constructed once in `Initialize` and reused for the whole
batch. A mid-run outage of `SAIF.Agency.Api` therefore skips every remaining
term instead of failing fast, which is why the summary mail lists affected
policy numbers.
- `Oracle.ManagedDataAccess` 21.11.0 is pinned by a binding redirect to match the
version `SAIF.Framework.Data.NHibernate` was built against. Upgrading it for
this application alone reintroduces the redirect conflict.
- `Newtonsoft.Json` 13.0.3 arrives both directly and transitively through
`SAIF.Web.API.Clients`; the redirect in `App.config` is what keeps the two
consistent at run time.
- The application has no project references, so nothing in this repository can be
changed in a way that affects a run without a package version change. That
makes deployments predictable but means a fix in the agency client requires a
package release rather than a rebuild.
## Related documentation
- [Application index](index.md)
- [Overview](overview.md)
- [Architecture](architecture.md)
- [Run lifecycle](run-lifecycle.md)
- [Arguments](arguments.md)
- [Configuration](configuration.md)
- [Operations and processes](operations-processes.md)
- [Business rules](business-rules.md)
- [Data model](data-model.md)
- [Operational runbook](operational-runbook.md)
- [Tech debt](tech-debt.md)
## Sources
- `src/SAIF.Policy.RenewalNotice/SAIF.Policy.RenewalNotice.csproj`
- `src/SAIF.Policy.RenewalNotice/packages.config`
- `src/SAIF.Policy.RenewalNotice/App.config`
- `src/SAIF.Policy.RenewalNotice/Program.cs`
- `src/SAIF.Policy.RenewalNotice/AgentResolver.cs`
- `src/SAIF.Policy.RenewalNotice/Mappings/RenewalNoticeMap.cs`