# DependencyInjection

- File ID: file:r7svsj:dependencyinjection-cs
- Path: NexusReader.Infrastructure/DependencyInjection.cs
- Role: service-registration
- Layer: infrastructure

## Purpose

Registers and configures infrastructure services (persistence, external clients, AI/embedding, background jobs, authorization, and scoped application services) into the DI container for the NexusReader application.

## Key Details

Conditional DB provider selection (Postgres vs Sqlite), conditional Hangfire registration when Postgres present, AI resilience pipeline with custom exception predicate and configurable retry attempts, AI API key presence warning, multiple scoped service registrations to align with AppDbContext lifetime.

## Symbols

- DependencyInjection: Registers and configures infrastructure services (persistence, external clients, AI/embedding, background jobs, authorization, and scoped application services) into the DI container for the NexusReader application.
- AddInfrastructure(): Configures and registers persistence (Postgres/Sqlite), external clients (Qdrant, Neo4j), Hangfire, AI settings/pipelines/clients, application service implementations, and authorization into the DI container.
- Assembly(): Exposes the assembly that contains the DependencyInjection class (useful for scanning/registration reflection).
- DependencyInjection: Static DI composition class that exposes AddInfrastructure and the assembly reference for the Infrastructure layer.
- IInfrastructureMarker: Marker interface used to identify the infrastructure assembly/types during scanning or composition.
- InfrastructureMarker: Internal concrete implementation of IInfrastructureMarker used solely to register a marker instance in DI.

## Dependencies

- imports NexusReader.Infrastructure/Services/KnowledgeService.cs
- imports NexusReader.Infrastructure/Services/EpubReaderService.cs
- imports NexusReader.Infrastructure/Services/EpubMetadataExtractor.cs
- imports NexusReader.Infrastructure/Services/BookStorageService.cs
- imports NexusReader.Infrastructure/Persistence/EbookRepository.cs
- imports NexusReader.Infrastructure/RealTime/SignalRSyncBroadcaster.cs

## Calls

- No resolved calls.

## Unresolved References

- dependency-target: NexusReader.Data.Persistence/AppDbContext.cs
- dependency-target: NexusReader.Application.Security.Authorization/ProUserHandler.cs
- call-target: NexusReader.Data.Persistence/AppDbContext.cs
- call-target: unknown
- call-target: unknown
- call-target: unknown
- call-target: unknown
- call-target: unknown
- call-target: unknown
- call-target: NexusReader.Infrastructure/Configuration/AiSettings.cs
- call-target: unknown
- call-target: unknown
- call-target: unknown
- call-target: unknown
- call-target: unknown
- call-target: NexusReader.Infrastructure/Services/KnowledgeService.cs
- call-target: NexusReader.Infrastructure/Services/EpubReaderService.cs
- call-target: NexusReader.Infrastructure/Services/EpubMetadataExtractor.cs
- call-target: NexusReader.Infrastructure/Services/BookStorageService.cs
- call-target: NexusReader.Infrastructure/Persistence/EbookRepository.cs
- call-target: NexusReader.Infrastructure/RealTime/SignalRSyncBroadcaster.cs
- call-target: NexusReader.Application.Security.Authorization/ProUserHandler.cs
- call-target: self
- call-target: self

## Coverage

- Symbols: 6
- Executable symbols: 2
- Executable symbols with control flow: 2
- Grounded edges: 12
- Unresolved references: 24
- Control-flow fragments: 2
- Unresolved jumps: 22
- Unsupported constructs: 0
- Control-flow coverage: 100%
- Required diagrams: 2
- Generated diagrams: 4

## Control Flow Fragments

- AddInfrastructure: 61 nodes, 67 edges, 21 jumps, 0 unsupported constructs
- Assembly: 4 nodes, 3 edges, 1 jumps, 0 unsupported constructs

## Diagrams

### DependencyInjection Neighborhood

_Warnings: diagram file_r7svsj_dependencyinjection_cs_neighborhood_view exceeds preferred complexity thresholds (13 nodes, 6 edges)._

```mermaid
---
config:
  flowchart:
    defaultRenderer: "elk"
---
flowchart LR
    class_k4fx0v_dependencyinjection("DependencyInjection")
    file_r7svsj_dependencyinjection_cs("DependencyInjection")
    method_1c1pgjw_assembly[["Assembly()"]]
    method_7atrx1_addinfrastructure[["AddInfrastructure()"]]
    file_10i5sd6_signalrsyncbroadcaster_cs[/"SignalRSyncBroadcaster"/]
    file_14qnurl_bookstorageservice_cs[/"BookStorageService"/]
    file_27eki7_knowledgeservice_cs[/"KnowledgeService"/]
    file_d3gg9l_epubmetadataextractor_cs[/"EpubMetadataExtractor"/]
    file_q4k94a_epubreaderservice_cs[/"EpubReaderService"/]
    file_veuxa3_ebookrepository_cs[/"EbookRepository"/]
    type_14djij0_infrastructuremarker[/"InfrastructureMarker"/]
    type_1f52ore_dependencyinjection[/"DependencyInjection"/]
    type_1y9p8ya_iinfrastructuremarker[/"IInfrastructureMarker"/]
    file_r7svsj_dependencyinjection_cs -->|SignalRSyncBroadcaster| file_10i5sd6_signalrsyncbroadcaster_cs
    file_r7svsj_dependencyinjection_cs -->|BookStorageService| file_14qnurl_bookstorageservice_cs
    file_r7svsj_dependencyinjection_cs -->|KnowledgeService| file_27eki7_knowledgeservice_cs
    file_r7svsj_dependencyinjection_cs -->|EpubMetadataExtractor| file_d3gg9l_epubmetadataextractor_cs
    file_r7svsj_dependencyinjection_cs -->|EpubReaderService| file_q4k94a_epubreaderservice_cs
    file_r7svsj_dependencyinjection_cs -->|EbookRepository| file_veuxa3_ebookrepository_cs
```

### DependencyInjection Execution Overview

_Warnings: diagram file_r7svsj_dependencyinjection_cs_execution_view exceeds preferred complexity thresholds (25 nodes, 24 edges)._

```mermaid
---
config:
  flowchart:
    defaultRenderer: "elk"
---
flowchart TD
    class_k4fx0v_dependencyinjection("DependencyInjection")
    method_1c1pgjw_assembly[["Assembly()"]]
    method_7atrx1_addinfrastructure[["AddInfrastructure()"]]
    unresolved_unresolved_10n4wv1_call_target{"Unresolved: InfrastructureMarker (type)"}
    unresolved_unresolved_134hl5l_call_target{"Unresolved: ShouldHandle predicate"}
    unresolved_unresolved_15cp2jv_call_target{"Unresolved: AiSettings (type)"}
    unresolved_unresolved_15p1osa_call_target{"Unresolved: SignalRSyncBroadcaster (type)"}
    unresolved_unresolved_19yvsnv_call_target{"Unresolved: EpubReaderService (type)"}
    unresolved_unresolved_1a0lsd0_call_target{"Unresolved: AppDbContext (type)"}
    unresolved_unresolved_1e9zmi6_call_target{"Unresolved: GraphDatabase.Driver"}
    unresolved_unresolved_1en7f0v_call_target{"Unresolved: BookStorageService (type)"}
    unresolved_unresolved_1qfa48h_call_target{"Unresolved: AddDbContextFactory<T>"}
    unresolved_unresolved_1quafzl_call_target{"Unresolved: EpubMetadataExtractor (type)"}
    unresolved_unresolved_1s64w8s_call_target{"Unresolved: AddHangfire"}
    unresolved_unresolved_1sopn1x_call_target{"Unresolved: AddChatClient"}
    unresolved_unresolved_1xf24ib_call_target{"Unresolved: AddResiliencePipeline"}
    unresolved_unresolved_72pwa6_call_target{"Unresolved: EbookRepository (type)"}
    unresolved_unresolved_err9l6_call_target{"Unresolved: AddEmbeddingGenerator"}
    unresolved_unresolved_fkfwxl_call_target{"Unresolved: typeof(DependencyInjection).Assembly"}
    unresolved_unresolved_grr5wo_call_target{"Unresolved: ProUserHandler (type)"}
    unresolved_unresolved_kw71kk_call_target{"Unresolved: AddSingleton<QdrantClient>"}
    unresolved_unresolved_lpwlzz_call_target{"Unresolved: AddHangfireServer"}
    unresolved_unresolved_qnp595_call_target{"Unresolved: AddDbContext<T>"}
    unresolved_unresolved_rm4h5e_call_target{"Unresolved: Get<T> (IConfigurationSection)"}
    unresolved_unresolved_t9z36n_call_target{"Unresolved: KnowledgeService (type)"}
    class_k4fx0v_dependencyinjection -->|contains| method_1c1pgjw_assembly
    class_k4fx0v_dependencyinjection -->|contains| method_7atrx1_addinfrastructure
    method_1c1pgjw_assembly -->|unresolved call| unresolved_unresolved_fkfwxl_call_target
    method_7atrx1_addinfrastructure -->|unresolved call| unresolved_unresolved_10n4wv1_call_target
    method_7atrx1_addinfrastructure -->|unresolved call| unresolved_unresolved_134hl5l_call_target
    method_7atrx1_addinfrastructure -->|unresolved call| unresolved_unresolved_15cp2jv_call_target
    method_7atrx1_addinfrastructure -->|unresolved call| unresolved_unresolved_15p1osa_call_target
    method_7atrx1_addinfrastructure -->|unresolved call| unresolved_unresolved_19yvsnv_call_target
    method_7atrx1_addinfrastructure -->|unresolved call| unresolved_unresolved_1a0lsd0_call_target
    method_7atrx1_addinfrastructure -->|unresolved call| unresolved_unresolved_1e9zmi6_call_target
    method_7atrx1_addinfrastructure -->|unresolved call| unresolved_unresolved_1en7f0v_call_target
    method_7atrx1_addinfrastructure -->|unresolved call| unresolved_unresolved_1qfa48h_call_target
    method_7atrx1_addinfrastructure -->|unresolved call| unresolved_unresolved_1quafzl_call_target
    method_7atrx1_addinfrastructure -->|unresolved call| unresolved_unresolved_1s64w8s_call_target
    method_7atrx1_addinfrastructure -->|unresolved call| unresolved_unresolved_1sopn1x_call_target
    method_7atrx1_addinfrastructure -->|unresolved call| unresolved_unresolved_1xf24ib_call_target
    method_7atrx1_addinfrastructure -->|unresolved call| unresolved_unresolved_72pwa6_call_target
    method_7atrx1_addinfrastructure -->|unresolved call| unresolved_unresolved_err9l6_call_target
    method_7atrx1_addinfrastructure -->|unresolved call| unresolved_unresolved_grr5wo_call_target
    method_7atrx1_addinfrastructure -->|unresolved call| unresolved_unresolved_kw71kk_call_target
    method_7atrx1_addinfrastructure -->|unresolved call| unresolved_unresolved_lpwlzz_call_target
    method_7atrx1_addinfrastructure -->|unresolved call| unresolved_unresolved_qnp595_call_target
    method_7atrx1_addinfrastructure -->|unresolved call| unresolved_unresolved_rm4h5e_call_target
    method_7atrx1_addinfrastructure -->|unresolved call| unresolved_unresolved_t9z36n_call_target
```

### AddInfrastructure() Control Flow

_Warnings: diagram method_7atrx1_addinfrastructure__fragment_diagram exceeds preferred complexity thresholds (61 nodes, 67 edges)._

```mermaid
---
config:
  flowchart:
    defaultRenderer: "elk"
---
flowchart TD
    method_7atrx1_addinfrastructure__call_105_AddEmbeddingGenerator[["AddEmbeddingGenerator"]]
    method_7atrx1_addinfrastructure__call_112_KnowledgeService_type_[["KnowledgeService (type)"]]
    method_7atrx1_addinfrastructure__call_113_EpubReaderService_type_[["EpubReaderService (type)"]]
    method_7atrx1_addinfrastructure__call_114_EpubMetadataExtractor_type_[["EpubMetadataExtractor (type)"]]
    method_7atrx1_addinfrastructure__call_118_BookStorageService_type_[["BookStorageService (type)"]]
    method_7atrx1_addinfrastructure__call_121_EbookRepository_type_[["EbookRepository (type)"]]
    method_7atrx1_addinfrastructure__call_124_SignalRSyncBroadcaster_type_[["SignalRSyncBroadcaster (type)"]]
    method_7atrx1_addinfrastructure__call_131_ProUserHandler_type_[["ProUserHandler (type)"]]
    method_7atrx1_addinfrastructure__call_132_InfrastructureMarker_type_[["InfrastructureMarker (type)"]]
    method_7atrx1_addinfrastructure__call_36_AddDbContextFactory_T_[["AddDbContextFactory<T>"]]
    method_7atrx1_addinfrastructure__call_36_AppDbContext_type_[["AppDbContext (type)"]]
    method_7atrx1_addinfrastructure__call_41_AddDbContext_T_[["AddDbContext<T>"]]
    method_7atrx1_addinfrastructure__call_57_AddSingleton_QdrantClient_[["AddSingleton<QdrantClient>"]]
    method_7atrx1_addinfrastructure__call_61_GraphDatabase_Driver[["GraphDatabase.Driver"]]
    method_7atrx1_addinfrastructure__call_66_AddHangfire[["AddHangfire"]]
    method_7atrx1_addinfrastructure__call_69_AddHangfireServer[["AddHangfireServer"]]
    method_7atrx1_addinfrastructure__call_72_AiSettings_type_[["AiSettings (type)"]]
    method_7atrx1_addinfrastructure__call_74_Get_T_IConfigurationSection_[["Get<T> (IConfigurationSection)"]]
    method_7atrx1_addinfrastructure__call_81_AddResiliencePipeline[["AddResiliencePipeline"]]
    method_7atrx1_addinfrastructure__call_85_ShouldHandle_predicate[["ShouldHandle predicate"]]
    method_7atrx1_addinfrastructure__call_99_AddChatClient[["AddChatClient"]]
    method_7atrx1_addinfrastructure__action_111_service_registration_111__linear("Register application-layer services")
    method_7atrx1_addinfrastructure__action_126_authorization_126__linear("Add 'ProUser' policy and handler")
    method_7atrx1_addinfrastructure__action_33_branch_33__condition{"Choose DB provider (Postgres vs Sqlite)"}
    method_7atrx1_addinfrastructure__action_33_branch_33__false("false")
    method_7atrx1_addinfrastructure__action_33_branch_33__merge("merge")
    method_7atrx1_addinfrastructure__action_33_branch_33__true("true")
    method_7atrx1_addinfrastructure__action_34_addinfrastructure_branch_34_0__condition{"!string.IsNullOrEmpty(pgConnectionString)"}
    method_7atrx1_addinfrastructure__action_34_addinfrastructure_branch_34_0__false("false")
    method_7atrx1_addinfrastructure__action_34_addinfrastructure_branch_34_0__merge("merge")
    method_7atrx1_addinfrastructure__action_34_addinfrastructure_branch_34_0__true("true")
    method_7atrx1_addinfrastructure__action_36_service_registration_36__linear("Register AppDbContext factory scoped")
    method_7atrx1_addinfrastructure__action_41_service_registration_41__linear("Register AppDbContext scoped")
    method_7atrx1_addinfrastructure__action_44_addinfrastructure_fallback_44_1__condition{"Falls back to alternate path"}
    method_7atrx1_addinfrastructure__action_44_addinfrastructure_fallback_44_1__false("otherwise")
    method_7atrx1_addinfrastructure__action_44_addinfrastructure_fallback_44_1__merge("merge")
    method_7atrx1_addinfrastructure__action_44_addinfrastructure_fallback_44_1__true("fallback")
    method_7atrx1_addinfrastructure__action_57_service_registration_57__linear("Register Qdrant client singleton")
    method_7atrx1_addinfrastructure__action_61_service_registration_61__linear("Register Neo4j driver singleton")
    method_7atrx1_addinfrastructure__action_64_addinfrastructure_branch_64_2__condition{"!string.IsNullOrEmpty(pgConnectionString)"}
    method_7atrx1_addinfrastructure__action_64_addinfrastructure_branch_64_2__false("false")
    method_7atrx1_addinfrastructure__action_64_addinfrastructure_branch_64_2__merge("merge")
    method_7atrx1_addinfrastructure__action_64_addinfrastructure_branch_64_2__true("true")
    method_7atrx1_addinfrastructure__action_64_branch_64__condition{"pgConnectionString not empty"}
    method_7atrx1_addinfrastructure__action_64_branch_64__false("skip hangfire")
    method_7atrx1_addinfrastructure__action_64_branch_64__merge("merge")
    method_7atrx1_addinfrastructure__action_64_branch_64__true("register hangfire")
    method_7atrx1_addinfrastructure__action_72_configure_72__linear("Bind configuration sections")
    method_7atrx1_addinfrastructure__action_76_addinfrastructure_branch_76_3__condition{"string.IsNullOrWhiteSpace(aiSettings.ApiKey) || aiSettings.ApiKey == \\"PLACEHOLDER\\""}
    method_7atrx1_addinfrastructure__action_76_addinfrastructure_branch_76_3__false("false")
    method_7atrx1_addinfrastructure__action_76_addinfrastructure_branch_76_3__merge("merge")
    method_7atrx1_addinfrastructure__action_76_addinfrastructure_branch_76_3__true("true")
    method_7atrx1_addinfrastructure__action_76_guard_clause_76__condition{"aiSettings.ApiKey null/whitespace or 'PLACEHOLDER'"}
    method_7atrx1_addinfrastructure__action_76_guard_clause_76__false("continue")
    method_7atrx1_addinfrastructure__action_76_guard_clause_76__merge("merge")
    method_7atrx1_addinfrastructure__action_76_guard_clause_76__true("warning")
    method_7atrx1_addinfrastructure__action_81_retry_policy_81__linear("AI retry resilience pipeline")
    method_7atrx1_addinfrastructure__action_99_service_registration_99__linear("Register AI chat and embedding clients")
    method_7atrx1_addinfrastructure__entry(["AddInfrastructure entry"])
    method_7atrx1_addinfrastructure__action_134_addinfrastructure_return_134_4__return(["Returns result"])
    method_7atrx1_addinfrastructure__action_134_return_134__return(["Return modified IServiceCollection"])
    method_7atrx1_addinfrastructure__action_111_service_registration_111__linear -->|registered as IKnowledgeService scoped| method_7atrx1_addinfrastructure__call_112_KnowledgeService_type_
    method_7atrx1_addinfrastructure__action_126_authorization_126__linear -->|registered as IAuthorizationHandler scoped| method_7atrx1_addinfrastructure__call_131_ProUserHandler_type_
    method_7atrx1_addinfrastructure__action_134_addinfrastructure_return_134_4__return -->|return| method_7atrx1_addinfrastructure__action_134_return_134__return
    method_7atrx1_addinfrastructure__action_33_branch_33__condition -->|false| method_7atrx1_addinfrastructure__action_33_branch_33__false
    method_7atrx1_addinfrastructure__action_33_branch_33__condition -->|true| method_7atrx1_addinfrastructure__action_33_branch_33__true
    method_7atrx1_addinfrastructure__action_33_branch_33__false -->|next| method_7atrx1_addinfrastructure__action_33_branch_33__merge
    method_7atrx1_addinfrastructure__action_33_branch_33__merge -->|next| method_7atrx1_addinfrastructure__action_34_addinfrastructure_branch_34_0__condition
    method_7atrx1_addinfrastructure__action_33_branch_33__true -->|next| method_7atrx1_addinfrastructure__action_33_branch_33__merge
    method_7atrx1_addinfrastructure__action_34_addinfrastructure_branch_34_0__condition -->|false| method_7atrx1_addinfrastructure__action_34_addinfrastructure_branch_34_0__false
    method_7atrx1_addinfrastructure__action_34_addinfrastructure_branch_34_0__condition -->|true| method_7atrx1_addinfrastructure__action_34_addinfrastructure_branch_34_0__true
    method_7atrx1_addinfrastructure__action_34_addinfrastructure_branch_34_0__false -->|next| method_7atrx1_addinfrastructure__action_34_addinfrastructure_branch_34_0__merge
    method_7atrx1_addinfrastructure__action_34_addinfrastructure_branch_34_0__merge -->|next| method_7atrx1_addinfrastructure__action_36_service_registration_36__linear
    method_7atrx1_addinfrastructure__action_34_addinfrastructure_branch_34_0__true -->|next| method_7atrx1_addinfrastructure__action_34_addinfrastructure_branch_34_0__merge
    method_7atrx1_addinfrastructure__action_36_service_registration_36__linear -->|pgConnectionString or sqliteConnectionString passed into UseNpgsql / UseSqlite options| method_7atrx1_addinfrastructure__call_36_AppDbContext_type_
    method_7atrx1_addinfrastructure__action_41_service_registration_41__linear -->|AppDbContext with DB provider options| method_7atrx1_addinfrastructure__call_41_AddDbContext_T_
    method_7atrx1_addinfrastructure__action_44_addinfrastructure_fallback_44_1__condition -->|otherwise| method_7atrx1_addinfrastructure__action_44_addinfrastructure_fallback_44_1__false
    method_7atrx1_addinfrastructure__action_44_addinfrastructure_fallback_44_1__condition -->|fallback| method_7atrx1_addinfrastructure__action_44_addinfrastructure_fallback_44_1__true
    method_7atrx1_addinfrastructure__action_44_addinfrastructure_fallback_44_1__false -->|next| method_7atrx1_addinfrastructure__action_44_addinfrastructure_fallback_44_1__merge
    method_7atrx1_addinfrastructure__action_44_addinfrastructure_fallback_44_1__merge -->|next| method_7atrx1_addinfrastructure__action_57_service_registration_57__linear
    method_7atrx1_addinfrastructure__action_44_addinfrastructure_fallback_44_1__true -->|next| method_7atrx1_addinfrastructure__action_44_addinfrastructure_fallback_44_1__merge
    method_7atrx1_addinfrastructure__action_57_service_registration_57__linear -->|new QdrantClient new Uri qdrantUrl| method_7atrx1_addinfrastructure__call_57_AddSingleton_QdrantClient_
    method_7atrx1_addinfrastructure__action_61_service_registration_61__linear -->|neo4jUrl, AuthTokens.None| method_7atrx1_addinfrastructure__call_61_GraphDatabase_Driver
    method_7atrx1_addinfrastructure__action_64_addinfrastructure_branch_64_2__condition -->|false| method_7atrx1_addinfrastructure__action_64_addinfrastructure_branch_64_2__false
    method_7atrx1_addinfrastructure__action_64_addinfrastructure_branch_64_2__condition -->|true| method_7atrx1_addinfrastructure__action_64_addinfrastructure_branch_64_2__true
    method_7atrx1_addinfrastructure__action_64_addinfrastructure_branch_64_2__false -->|next| method_7atrx1_addinfrastructure__action_64_addinfrastructure_branch_64_2__merge
    method_7atrx1_addinfrastructure__action_64_addinfrastructure_branch_64_2__merge -->|next| method_7atrx1_addinfrastructure__action_64_branch_64__condition
    method_7atrx1_addinfrastructure__action_64_addinfrastructure_branch_64_2__true -->|next| method_7atrx1_addinfrastructure__action_64_addinfrastructure_branch_64_2__merge
    method_7atrx1_addinfrastructure__action_64_branch_64__condition -->|skip hangfire| method_7atrx1_addinfrastructure__action_64_branch_64__false
    method_7atrx1_addinfrastructure__action_64_branch_64__condition -->|register hangfire| method_7atrx1_addinfrastructure__action_64_branch_64__true
    method_7atrx1_addinfrastructure__action_64_branch_64__false -->|next| method_7atrx1_addinfrastructure__action_64_branch_64__merge
    method_7atrx1_addinfrastructure__action_64_branch_64__merge -->|Configure Hangfire with PostgreSqlStorage using pgConnectionString| method_7atrx1_addinfrastructure__call_66_AddHangfire
    method_7atrx1_addinfrastructure__action_64_branch_64__true -->|next| method_7atrx1_addinfrastructure__action_64_branch_64__merge
    method_7atrx1_addinfrastructure__action_72_configure_72__linear -->|Configure and bind AiSettings from configuration| method_7atrx1_addinfrastructure__call_72_AiSettings_type_
    method_7atrx1_addinfrastructure__action_76_addinfrastructure_branch_76_3__condition -->|false| method_7atrx1_addinfrastructure__action_76_addinfrastructure_branch_76_3__false
    method_7atrx1_addinfrastructure__action_76_addinfrastructure_branch_76_3__condition -->|true| method_7atrx1_addinfrastructure__action_76_addinfrastructure_branch_76_3__true
    method_7atrx1_addinfrastructure__action_76_addinfrastructure_branch_76_3__false -->|next| method_7atrx1_addinfrastructure__action_76_addinfrastructure_branch_76_3__merge
    method_7atrx1_addinfrastructure__action_76_addinfrastructure_branch_76_3__merge -->|next| method_7atrx1_addinfrastructure__action_81_retry_policy_81__linear
    method_7atrx1_addinfrastructure__action_76_addinfrastructure_branch_76_3__true -->|next| method_7atrx1_addinfrastructure__action_76_addinfrastructure_branch_76_3__merge
    method_7atrx1_addinfrastructure__action_76_guard_clause_76__condition -->|continue| method_7atrx1_addinfrastructure__action_76_guard_clause_76__false
    method_7atrx1_addinfrastructure__action_76_guard_clause_76__condition -->|warning| method_7atrx1_addinfrastructure__action_76_guard_clause_76__true
    method_7atrx1_addinfrastructure__action_76_guard_clause_76__false -->|next| method_7atrx1_addinfrastructure__action_76_guard_clause_76__merge
    method_7atrx1_addinfrastructure__action_76_guard_clause_76__merge -->|next| method_7atrx1_addinfrastructure__action_76_addinfrastructure_branch_76_3__condition
    method_7atrx1_addinfrastructure__action_76_guard_clause_76__true -->|next| method_7atrx1_addinfrastructure__action_76_guard_clause_76__merge
    method_7atrx1_addinfrastructure__action_81_retry_policy_81__linear -->|calls| method_7atrx1_addinfrastructure__call_81_AddResiliencePipeline
    method_7atrx1_addinfrastructure__action_99_service_registration_99__linear -->|GeminiChatClient configured with AiSettings.ApiKey and ModelId| method_7atrx1_addinfrastructure__call_99_AddChatClient
    method_7atrx1_addinfrastructure__call_105_AddEmbeddingGenerator -->|next| method_7atrx1_addinfrastructure__action_111_service_registration_111__linear
    method_7atrx1_addinfrastructure__call_112_KnowledgeService_type_ -->|registered as IEpubReader transient| method_7atrx1_addinfrastructure__call_113_EpubReaderService_type_
    method_7atrx1_addinfrastructure__call_113_EpubReaderService_type_ -->|registered as IEpubMetadataExtractor transient| method_7atrx1_addinfrastructure__call_114_EpubMetadataExtractor_type_
    method_7atrx1_addinfrastructure__call_114_EpubMetadataExtractor_type_ -->|registered as IBookStorageService scoped| method_7atrx1_addinfrastructure__call_118_BookStorageService_type_
    method_7atrx1_addinfrastructure__call_118_BookStorageService_type_ -->|registered as IEbookRepository scoped| method_7atrx1_addinfrastructure__call_121_EbookRepository_type_
    method_7atrx1_addinfrastructure__call_121_EbookRepository_type_ -->|registered as ISyncBroadcaster scoped| method_7atrx1_addinfrastructure__call_124_SignalRSyncBroadcaster_type_
    method_7atrx1_addinfrastructure__call_124_SignalRSyncBroadcaster_type_ -->|next| method_7atrx1_addinfrastructure__action_126_authorization_126__linear
    method_7atrx1_addinfrastructure__call_131_ProUserHandler_type_ -->|registered as IInfrastructureMarker scoped| method_7atrx1_addinfrastructure__call_132_InfrastructureMarker_type_
    method_7atrx1_addinfrastructure__call_132_InfrastructureMarker_type_ -->|return| method_7atrx1_addinfrastructure__action_134_addinfrastructure_return_134_4__return
    method_7atrx1_addinfrastructure__call_36_AddDbContextFactory_T_ -->|next| method_7atrx1_addinfrastructure__action_41_service_registration_41__linear
    method_7atrx1_addinfrastructure__call_36_AppDbContext_type_ -->|AppDbContext factory with DB provider options| method_7atrx1_addinfrastructure__call_36_AddDbContextFactory_T_
    method_7atrx1_addinfrastructure__call_41_AddDbContext_T_ -->|fallback| method_7atrx1_addinfrastructure__action_44_addinfrastructure_fallback_44_1__condition
    method_7atrx1_addinfrastructure__call_57_AddSingleton_QdrantClient_ -->|next| method_7atrx1_addinfrastructure__action_61_service_registration_61__linear
    method_7atrx1_addinfrastructure__call_61_GraphDatabase_Driver -->|next| method_7atrx1_addinfrastructure__action_64_addinfrastructure_branch_64_2__condition
    method_7atrx1_addinfrastructure__call_66_AddHangfire -->|start Hangfire server| method_7atrx1_addinfrastructure__call_69_AddHangfireServer
    method_7atrx1_addinfrastructure__call_69_AddHangfireServer -->|next| method_7atrx1_addinfrastructure__action_72_configure_72__linear
    method_7atrx1_addinfrastructure__call_72_AiSettings_type_ -->|Bind AiSettings section into AiSettings instance| method_7atrx1_addinfrastructure__call_74_Get_T_IConfigurationSection_
    method_7atrx1_addinfrastructure__call_74_Get_T_IConfigurationSection_ -->|next| method_7atrx1_addinfrastructure__action_76_guard_clause_76__condition
    method_7atrx1_addinfrastructure__call_81_AddResiliencePipeline -->|exception -> check message contains 429 / Too Many Requests / quota / 503 / ServiceUnavailable / demand| method_7atrx1_addinfrastructure__call_85_ShouldHandle_predicate
    method_7atrx1_addinfrastructure__call_85_ShouldHandle_predicate -->|next| method_7atrx1_addinfrastructure__action_99_service_registration_99__linear
    method_7atrx1_addinfrastructure__call_99_AddChatClient -->|GeminiEmbeddingGenerator configured with ApiKey and EmbeddingModel| method_7atrx1_addinfrastructure__call_105_AddEmbeddingGenerator
    method_7atrx1_addinfrastructure__entry -->|next| method_7atrx1_addinfrastructure__action_33_branch_33__condition
```

### Assembly() Control Flow

```mermaid
flowchart TD
    method_1c1pgjw_assembly__call_137_typeof_DependencyInjection_Assembly[["typeof(DependencyInjection).Assembly"]]
    method_1c1pgjw_assembly__action_137_expose_metadata_137__linear("Return assembly for scanning")
    method_1c1pgjw_assembly__entry(["Assembly entry"])
    method_1c1pgjw_assembly__implicit_return(["return"])
    method_1c1pgjw_assembly__action_137_expose_metadata_137__linear -->|reflection on DependencyInjection type| method_1c1pgjw_assembly__call_137_typeof_DependencyInjection_Assembly
    method_1c1pgjw_assembly__call_137_typeof_DependencyInjection_Assembly -->|return| method_1c1pgjw_assembly__implicit_return
    method_1c1pgjw_assembly__entry -->|next| method_1c1pgjw_assembly__action_137_expose_metadata_137__linear
```

## Diagram Validation

- Status: warn
- Warning: Control-flow extraction left 22 unresolved jumps.
- Warning: neighborhood-view: diagram file_r7svsj_dependencyinjection_cs_neighborhood_view exceeds preferred complexity thresholds (13 nodes, 6 edges).
- Warning: execution-overview: diagram file_r7svsj_dependencyinjection_cs_execution_view exceeds preferred complexity thresholds (25 nodes, 24 edges).
- Warning: control-flow: diagram method_7atrx1_addinfrastructure__fragment_diagram exceeds preferred complexity thresholds (61 nodes, 67 edges).
