Database and Always-Valid Domain Model

1. Always-Valid Domain Model

Just a quick reminder on what Always-Valid Domain Model is. It’s a guideline saying that domain classes should always guard themselves from becoming invalid.

Always-valid domain model

2. Always-valid boundary and the database

Now the question is: where does the database belong on the above diagram? Is it part of the external world or is it part of the always-valid boundary?

Always-valid domain model and the database

3. Always-valid boundary and a shared database

Sometimes, you just can’t have a dedicated database for your application. This might be due to historic reasons that you can’t do anything about, which is often the case in legacy applications.

Always-valid domain model and a shared database

4. Managed vs unmanaged dependencies

This guideline of treating the application database as part of the always-valid boundary extends to all out-of-process dependencies interactions with which aren’t visible to external applications. I call such dependencies managed dependencies.

5. Guarding vs validating

Note that it’s not to say that you can’t ever guard against data coming from the application database. You can. Keep in mind though that the concept of guarding is different from validation.

Validation vs guarding
public class Customer : Entity
{
private string _name;
public virtual CustomerName Name
{
get => (CustomerName)_name; // Throws if conversion fails
set => _name = value;
}
}
get => (CustomerName)_name;
public class Student : Entity
{
public Email Email { get; private set; }
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Student>(x =>
{
// Calling .Value throws if conversion from string to Email fails
x.Property(p => p.Email)
.HasConversion(p => p.Value, p => Email.Create(p).Value);
}
Email.Create(p).Value

6. The use of ORMs within and outside of the always-valid boundary

There’s a common question about how to use an ORM within and outside of the always-valid boundary. It goes something like this:

7. Summary

  • Treat the application database as part of the always-valid boundary
  • If the database is shared with other applications, segregate parts of it that are visible to other applications from parts that aren’t
  • This guideline extends to all managed dependencies, including the file system
  • You can still guard against data coming from the application database
  • Don’t use an ORM when working with a shared database

Subscribe

Subscribe to read more articles like this: https://enterprisecraftsmanship.com/subscribe

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store