---
title: BolMiddleware architecture
summary: Architectural responsibilities, boundaries, and interaction patterns.
status: draft
owner: SAIF IT Core Services
last_reviewed: 2026-10-12
library: BolMiddleware
reference_type: package
---

# BolMiddleware architecture

BolMiddleware is a net8.0 ASP.NET Core Razor class library shipped as a NuGet package. It gives consumer Razor Pages applications the Business Online (BOL) page chrome: shared layouts, menu and policy header view components, a chain of abstract PageModel base classes, and thin service facades over remote BOL, Policy, and SAIF platform API clients. Consumers adopt it by inheriting `BolRazorLayoutStartup` and deriving their pages from `BolContextModel`, `BolMenuModel`, or `BolPolicyModel`. The library has no host entry point and no database access; all persistence is delegated to remote APIs reached through internal client packages.

## Responsibilities
- Provide a startup base class (`BolRazorLayoutStartup`) that extends `OidcRazorStartup`, enables the legacy BOL authentication middleware, registers BOL services, and binds the `BasicAppMap` options.
- Register BOL services and the four API client packages through `RegisterBolServices`.
- Resolve and persist the BOL web context for every request through `BolContextModel`, using a short-lived cookie, the ASP.NET Core session, and the remote BOL Context API.
- Load the BOL menu for the current user and drive cross-application navigation through `BolMenuModel`.
- Load the policy header, validate access to the policy, and expose the policy association dropdown through `BolPolicyModel`.
- Ship four Razor layouts, three view components, shared partials, a menu navigation script, and compiled styles as static web assets.
- Offer optional consumer customization hooks as partial views under `MiddlewareIncludes/`.

## Component boundaries
- Host integration (`BolRazorLayoutStartup`, `BolServiceExtensions`): owns service registration and options binding; the middleware pipeline is inherited from `OidcRazorStartup` and is not defined here.
- Page pipeline (`BolContextModel`, `BolMenuModel`, `BolPolicyModel`): abstract PageModels that form an inheritance chain and hook the Razor Pages handler filter events.
- Service layer (`BolServicesContainer`, `SecurityService`, `WebContextService`, `MenuService`, `PolicyHeaderService`, `CookieService`, `ContextCookieHelperService`, `RequestHelper`): facades over the remote API clients and HTTP helpers; they catch exceptions and fall back to defaults.
- Presentation (RCL views and view components): `_PolicyLayout`, `_PolicyOnlyLayout`, `_ContextOnlyLayout`, `_MenuOnlyLayout`, and the `BolPolicyHeader`, `BolSideMenu`, and `BolTopMenu` view components render data supplied by the PageModel.
- Client script (`wwwroot/js/MenuNavigation.js`): intercepts menu link clicks and context box key presses and posts the context form for cross-application navigation.
- Remote dependencies (outside this library): BOL Context API, BOL Menu API, Policy Header API, Policy Core API, the SAIF security client, and the SAIF environment client. Their endpoints and transport are package internals and unknown** from this repository.

## Interaction model
- A consumer page derives from a BolMiddleware PageModel. On handler selection the model reads the `BolContext` cookie and the `ApplicationName` setting.
- On handler execution the model resolves the web context in priority order: cookie, referring application lookup, context id (`cid` query or `WebContextId` form value), then session.
- State is held in three layers: the `BolContext` HttpOnly cookie (10 second lifetime), ASP.NET Core session JSON for the context, menu, and policy header, and the remote BOL Context API for cross-application persistence.
- `BolMenuModel` loads the menu through `IMenuService`, and `BolPolicyModel` loads the policy header through `IPolicyHeaderService` and validates the policy through `SecurityService`, which calls `IPolicyCoreApiClient.IsValidPolicyForUser`. External user information comes from a different client: `BolContextModel` calls `SecurityService.GetCurrentExternalUserAsync` from `OnPageHandlerExecuting`, which calls `ISecurityClient.GetExternalUser`.
- Layouts render the BOL chrome by invoking the view components with data from the PageModel.
- Cross-application navigation hands the context off through a `cid` value or a referring application lookup.
- Two sync-over-async calls exist in the page pipeline: the external user lookup in `BolContextModel` and the policy validation in `BolPolicyModel`.

## Architecture diagram
The following diagram shows high-level component interactions.

```mermaid
flowchart TD
	Consumer[Consumer Razor Pages app] --> Startup[BolRazorLayoutStartup]
	Consumer --> Models[BolContextModel to BolMenuModel to BolPolicyModel]
	Startup --> Reg[RegisterBolServices]
	Models --> Container[BolServicesContainer]
	Models --> Facades[Context Menu PolicyHeader Security services]
	Models --> Cookie[Cookie and session state]
	Facades --> Clients[Internal API client packages]
	Clients --> Remote[BOL and Policy APIs]
	Models --> Layouts[Layouts and view components]
	Layouts --> Script[MenuNavigation.js]
```

## Sequence diagram
The following diagram shows the primary request/response sequence.

```mermaid
sequenceDiagram
	participant Browser
	participant Page as Consumer page model
	participant Ctx as WebContextService
	participant Menu as MenuService
	participant Hdr as PolicyHeaderService
	Browser->>Page: GET page with cid or cookie
	Page->>Page: Read BolContext cookie and session
	Page->>Ctx: GetContext by context id or session
	Ctx-->>Page: Context result
	Page->>Menu: GetMenu for current user
	Menu-->>Page: Menu data
	Page->>Hdr: GetHeader for policy
	Hdr-->>Page: Policy header
	Page-->>Browser: Razor page with BOL layout
```

## Design constraints
- The library targets net8.0 only and requires the `Microsoft.AspNetCore.App` shared framework.
- The startup pipeline order is inherited from `OidcRazorStartup` and is unknown** from this repository.
- `ISecurityClient`, `IEnvironmentClient`, and `ISaifLogService` are resolved but not registered here; they are expected from the base startup*.
- `AddSession()` is called, but `UseSession()` and a distributed cache are not configured in this library; whether the base startup enables session middleware is unknown**.
- `IBolContextApiClient` is registered twice; the last registration wins for single resolution.
- `IAppMap` resolves a default `BasicAppMap` instance, while views read the configured `IOptions<BasicAppMap>` directly.
- Singleton facades depend on API clients whose lifetimes are set inside the packages, so a lifetime capture risk is unknown**.
- View component `InvokeAsync` methods are declared async but contain no `await`.

> **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.

## Related documentation
- [Index](index.md)
- [Overview](overview.md)
- [Dependencies](dependencies.md)
- [Configuration](configuration.md)
- [Operations and processes](operations-processes.md)
- [Business rules](business-rules.md)
- [Security and authorization](security-authorization.md)
- [Service registration](service-registration.md)
- [API reference](api/index.md)

## Sources
- src/BolMiddleware/BolMiddleware.csproj
- src/BolMiddleware/BolRazorLayoutStartup.cs
- src/BolMiddleware/Extensions/BolMiddlewareExtensions.cs
- src/BolMiddleware/Models/BolContextModel.cs
- src/BolMiddleware/Models/BolMenuModel.cs
- src/BolMiddleware/Models/BolPolicyModel.cs
- src/BolMiddleware/Services/BolServicesContainer.cs
- src/BolMiddleware/Services/Context/WebContextService.cs
- src/BolMiddleware/Services/Menu/MenuService.cs
- src/BolMiddleware/Services/Headers/Policy/PolicyHeaderService.cs
- src/BolMiddleware/Services/Security/SecurityService.cs
- src/BolMiddleware/ViewComponents/BolPolicyHeaderViewComponent.cs
- src/BolMiddleware/Pages/Shared/_PolicyLayout.cshtml
- src/BolMiddleware/wwwroot/js/MenuNavigation.js
