Skip to content

Architecture and Extension Points

Mike Christensen edited this page Aug 28, 2026 · 1 revision

Architecture and extension points

KitchenPC's fluent API sits above replaceable context, persistence, search, provisioning, identity, modeler-loading, and NLP-data boundaries.

Persistence adapter

DBContext delegates storage to IDBAdapter. An adapter owns recipe reads/search/writes, ingredients, ratings, menus, queues, shopping lists, aggregation inputs, provisioning, and loaders used to construct optional indexes.

Implement IDBAdapter when the application needs a fundamentally different store. This is a large integration surface; start by reading DatabaseAdapter and exercising the Core unit tests against your implementation. Subclassing or configuring the existing adapter is usually smaller when the target remains relational.

Search provider

ISearchProvider isolates RecipeQuery execution. Register a provider through:

DatabaseAdapter.Configure
   .DatabaseConfiguration(/* NHibernate config */)
   .SearchProvider(adapter => new MySearchProvider(adapter));

The provider must honor paging, filtering, sort semantics, identity-dependent fields where applicable, and return both RecipeBrief[] and total count. NHSearch.Instance is the built-in SQL implementation.

Identity

Context builders accept Func<AuthIdentity>. In a background application this may be constant; in a server use AsUserContext or the ASP.NET Core integration. Keep authentication outside KitchenPC. The engine consumes a resolved identity; it does not issue cookies or tokens.

Provisioning

Implement IProvisionSource to export a DataStore and IProvisionTarget to initialize/import it. This permits snapshot-to-database migration and custom seed pipelines. Treat initialization as destructive unless your implementation explicitly guarantees otherwise.

NLP data loaders and tracing

The NLP engine obtains ingredient, unit, form, prep-note, and anomaly synonym data through loader interfaces. Custom contexts/adapters can provide domain-specific vocabulary while reusing the parser. ITracer provides detailed parser observability without coupling the engine to one diagnostics destination.

Recipe modeler loader and profiles

IModelerLoader supplies recipe, ingredient, and rating graph bindings. IUserProfile supplies application-specific preferences and pantry state. These boundaries let a model use an external profile service without changing the graph engine.

Categorization inputs

Categorization interfaces provide recipe classifications and ingredient commonality/metadata. The engine can derive meal, diet, nutrition, taste, and skill tags only as accurately as these inputs allow.

Database conventions

DatabaseAdapterBuilder.AddConvention accepts Fluent NHibernate conventions. This can customize enum or column mapping while retaining the adapter. Database-specific types referenced by conventions must exist before InitializeStore() runs.

Design advice

  • Prefer the smallest extension point that meets the requirement.
  • Preserve IKPCContext semantics so fluent callers remain portable.
  • Add contract tests for identity isolation, batching, cancellation, aggregation, and missing records.
  • Keep UI formatting, HTML sanitization, authentication, and HTTP concerns outside Core.
  • Document any behavior that differs from DatabaseAdapter/NHSearch.

Clone this wiki locally