Architecture¶
OnBaseKeywordSync is a single-project executable: a SaifStandardProgramBase runner constructs an Autofac container, resolves the OnBaseKeywordSyncRunner application, and the application constructs its own collaborators with new rather than resolving them from the container. There is no unit-of-work/database layer — every integration is a remote HTTP or SOAP call.
Layer diagram¶
flowchart TD
MAIN[Main entry point] --> RUNNER["Program : SaifStandardProgramBase"]
RUNNER --> ARGS["ArgumentContainer : StandardArgumentContainerBase<br>(no arguments declared)"]
RUNNER --> DI["Autofac container<br>RegisterAppDependencies"]
DI --> APP["OnBaseKeywordSyncRunner : ConsoleBase"]
APP --> IMG["ImagingApiClient<br>JsonHttpClient v1/Integration"]
APP --> UPD["KeywordUpdater<br>per-record decision logic"]
UPD --> OBC["OnBaseKeywordSyncClient<br>builds OBE form data"]
UPD --> HELP["KeywordHelper<br>Y/N flag translation"]
OBC --> WCF["HylandOutBoundContractClient<br>WCF basicHttpBinding"]
WCF --> ONBASE["(OnBase Keyword Update SOAP service)"]
IMG --> IMGAPI["(Imaging API<br>ImageKeywordSyncs endpoints)"]
APP --> LOG[IConsoleLogService]
DI --> ENV[IEnvironmentService]
MainconstructsProgramand callsRun(); the framework builds the argument container, runs argument resolution (a no-op here since no arguments are declared), and builds the Autofac container.RegisterAppDependenciesregisters only framework-common services andIEnvironmentService/IConsoleLogService— noDatabaseConfigis registered, so no NHibernate unit-of-work layer exists.OnBaseKeywordSyncRunner.Execute()constructsImagingApiClient,KeywordUpdater,OnBaseKeywordSyncClient, andKeywordHelperdirectly withnew, hand-propagatingIEnvironmentServiceandIConsoleLogServiceto each.- All persisted state lives behind the Imaging API and OnBase SOAP service; this process holds no database connection.
Component responsibilities¶
| Component | Type | Responsibility |
|---|---|---|
Program |
Runner (SaifStandardProgramBase<,>) |
Composition root, argument container factory, application factory |
ArgumentContainer |
Argument container | Declares (zero) command-line arguments |
OnBaseKeywordSyncRunner |
Application (ConsoleBase<>) |
Initialize / Execute / Finish business logic — the entire run |
ImagingApiClient |
Service | REST client for the Imaging API ImageKeywordSyncs endpoints |
KeywordUpdater |
Service | Per-record orchestration, send/skip decision logic, and console narration |
OnBaseKeywordSyncClient |
Service | WCF/SOAP client wrapper that builds and sends the OnBase E-Form payload |
KeywordHelper |
Service | Keyword value translation (Y/N flag rules) |
HylandOutBoundContractClient (generated) |
WCF proxy | SOAP client for the OnBase keyword-update service |
Composition root¶
Program.RegisterAppDependencies(ContainerBuilder builder) calls builder.RegisterCommonDependencies(Environment.UserName, new[] { typeof(Program).Assembly }) with no DatabaseConfig arguments, so the framework's NHibernate unit-of-work and connection registration paths are skipped entirely†. The class-map assembly array points at the executable's own assembly, which contains no ClassMap<TEntity> types, so no mappings are registered.
builder.Register(x => new LogService(x.Resolve<IEnvironmentService>())).As<ILogService>() registers SAIF.Services.LogService as ILogService, but it is never resolved by application code — the application logs only through IConsoleLogService.
builder.ConfigureOpenTelemetry(options => { options.Owner = "Documents"; }) is called after the LogService registration, so LogService receives no LoggerProvider and OpenTelemetry log correlation through it is not wired*.
| Registration | Lifetime | Resolved by | Purpose |
|---|---|---|---|
IEnvironmentService → WindowsEnvironmentService |
InstancePerLifetimeScope† |
OnBaseKeywordSyncRunner, ImagingApiClient, KeywordUpdater, OnBaseKeywordSyncClient |
Environment API configuration retrieval |
IConsoleLogService → ConsoleLogService |
InstancePerLifetimeScope† |
OnBaseKeywordSyncRunner (forwarded to KeywordUpdater) |
Console and file logging surface |
ILogService → LogService |
InstancePerDependency (default) |
Not resolved anywhere | Registered but unused |
| OpenTelemetry providers | SingleInstance† |
Framework internals | Traces/logs export with resource owner documents† |
Design constraints¶
- No database connection is ever established —
RegisterCommonDependenciesis called with noDatabaseConfig, so noIUnitOfWorkis available to this application*. - Application collaborators are constructed with
new, not resolved from Autofac, so the container's role ends at theOnBaseKeywordSyncRunnerapplication object. - No transaction or unit-of-work boundary exists: the Imaging API
MarkProcessedcalls and the OnBase SOAP calls are each independent remote operations with no compensating action on failure*. - The runner's
TAppgeneric argument is the abstract baseConsoleBase<ArgumentContainer>, not the concreteOnBaseKeywordSyncRunner; the container registers and resolves the application by its base type, with the concrete type supplied only by theCreateApplicationfactory.
Integration points¶
| System | Type | Purpose |
|---|---|---|
Imaging API ({imagingapiurl}v1/Integration) |
REST (JSON over HTTP) | Read unprocessed keyword syncs, clear invalid person updates, mark records processed |
| OnBase keyword-update service | SOAP (WCF basicHttpBinding) |
Apply keyword updates to OnBase documents |
Environment API (IEnvironmentService) |
Configuration | All runtime settings and both endpoint addresses |
| OpenTelemetry | Telemetry | Traces/logs export with resource owner documents† |
Local file system (C:\temp\OnBaseKeywordSync_Debug.log) |
Debug-only log tee | Truncated at every process start, written only when a debugger is attached |
Inherited framework behavior¶
Lifecycle orchestration, argument parsing, exit-code mapping, and header/footer logging are inherited from SAIF.Framework.Windows and are not re-documented here.†
Related documentation¶
- Application index
- Overview
- Run lifecycle
- Arguments
- Dependencies
- Configuration
- Operations and processes
- Business rules
- Operational runbook
- Tech debt
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¶
OnBaseKeywordSync/Program.csOnBaseKeywordSync/OnBaseKeywordSyncRunner.csOnBaseKeywordSync/Services/ImagingApiClient.csOnBaseKeywordSync/Services/KeywordUpdater.csOnBaseKeywordSync/Services/OnBaseKeywordSyncClient.csOnBaseKeywordSync/Services/KeywordHelper.csOnBaseKeywordSync/Service References/OnBase/Reference.cs