Skip to content

Extensibility

Shannon Lewis edited this page Jul 7, 2021 · 8 revisions

Nevermore is designed to be extensible, and you can change most of its behavior by implementing some types and registering them.

Mapping extensions

Out of the box Nevermore knows how to serialize objects, handle enums, and map common database types to .NET types. However, Nevermore provides also three ways to extend these behaviors. To understand what each one is for, it's useful to think about how Nevermore maps columns.

When you execute a query in Nevermore, Nevermore generates and compiles a C# expression tree that knows how to handle read your document from the query. What it does would look a bit like the code in the diagram below.

Extensibility

See the following sections for details on each:

If you want to control how inherited types appear in serialized JSON (not just the root document), you can use a custom JsonContract or use ISerializationBinder (see tip).

Primary Key Handlers

A primary key handler is similar to a type handler, it's job is to map the Id column to/from a CLR type (e.g. string, int, long, Guid). Its implementation is different though, due to how it gets used during Insert and Delete operations. For more details see Primary Key Handlers.

Hooks

Hooks allow you to run code when Nevermore is inserting, updating or deleting documents. It's a good way to plug in general logic like auditing.

Learn more about hooks

Everything else

Most other things can be extended, from the serializer being used (implement IDocumentSerailizer) to the way types are read from the database. Everything is registered in the IRelationalStoreConfiguration, and you can create custom implementations and assign them there. If you're not sure, consider raising an issue.

Of note:

  • IDocumentSerializer lets you provide your own JSON (or compressed JSON) serializer
  • ISqlCommandFactory lets you control how DbCommand is set up, or to add instrumentation, before each query