Refactoring strategy

By cluster refactoring, I mean when we just move models (collections of entities) among contexts.

Here I am showing a strategy for refactoring in terms of:

  • moving the model's ownership between contexts,
  • introducing new contexts
  • upgrading old contexts.
  • dropping contexts.

The problem arises because it looks overcomplicated d to make upfront decisions about contexts. Consider that an application may start, for simplicity, with a single context and then, at a later stage, we may want to split it into multiple contexts.

Refactoring leaves the application service layer behavior unchanged.

The steps that may be followed are:

  • defining new contexts and eventually creating upgraded versions of current contexts
  • moving collection of entities from contexts to others.
  • creating an upgraded version of the application service layer using the new versions
  • applying the equivalent tests of the previous service layer to the new one.

About this latest point, a parametric testing strategy is also possible.

Here is an example of a list of tuples of multiple application version configurations with migration functions.

let allVersions =
    [
        (applicationPostgresStorage,        applicationPostgresStorage,       fun () -> () |> Result.Ok)
        (applicationShadowPostgresStorage,  applicationShadowPostgresStorage, fun () -> () |> Result.Ok)
        (applicationPostgresStorage,        applicationShadowPostgresStorage, applicationPostgresStorage._migrator.Value)

        (applicationMemoryStorage,          applicationMemoryStorage,         fun () -> () |> Result.Ok)
        (applicationShadowMemoryStorage,    applicationShadowMemoryStorage,   fun () -> () |> Result.Ok)
        (applicationMemoryStorage,          applicationShadowMemoryStorage,   applicationMemoryStorage._migrator.Value)
    ]

There are specific attributes to distinguish current and "upgrading" versions of elements of the application.

A migration function is needed to extract data from the current version and store it in the upgraded version.

Code here: MultiVersionsTests.fs