<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/a-domain-wrapper-in-c--krxzntmuh" -->

---
title: A Domain wrapper in C# | daily.dev
description: A C# library that enforces domain constraints at the type level, inspired by mathematical function domains. Instead of using primitive types like `int` or...
canonical: https://daily.dev/posts/a-domain-wrapper-in-c--krxzntmuh
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: A Domain wrapper in C# | daily.dev
og:description: A C# library that enforces domain constraints at the type level, inspired by mathematical function domains. Instead of using primitive types like `int` or...
og:url: https://daily.dev/posts/a-domain-wrapper-in-c--krxzntmuh
og:image: https://api.daily.dev/og/posts/KRXzNTmUH.png
og:image:alt: A Domain wrapper in C#
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# A Domain wrapper in C#

**[.NET](https://daily.dev/sources/dotnetsquad)** · [@vicvondoom](https://daily.dev/vicvondoom) · 4 min read · 0 upvotes · 0 comments

## Summary

A C# library that enforces domain constraints at the type level, inspired by mathematical function domains. Instead of using primitive types like `int` or `string` with implicit validation scattered throughout code, it models values as belonging to explicitly defined mathematical sets (e.g., Age ∈ [0, 120]). The approach centralizes validation logic, prevents invalid states from existing, and enables functional composition through Map/Bind operations. The library separates domain definitions from values and policies, making constraints structural rather than optional.

## Content

# Why This Project Exists

## Formal Domain Modeling Inspired by Mathematical Functions

------------------------------------------------------------------------

## 1. The Original Motivation

In mathematics, every function is defined over a **domain**.

For example:

f(x) = sqrt(x)

Domain: x ≥ 0

The function is not defined outside its domain.

However, in most software systems, we declare variables like this:

```
int age;
decimal price;
string username;
```

Formally, these types have extremely wide domains:

- `int` → \[-2,147,483,648 ... 2,147,483,647\]
- `decimal` → ±7.9 × 10²⁸
- `string` → virtually unlimited

But in real-world logic, we almost never mean that.

------------------------------------------------------------------------

## 2. The Real Problem

Consider:

```
int age;
```

Mathematically, the type allows:

age ∈ ℤ

But in reality:

age ∈ [0, 120]

Yet nothing in the type system enforces that.

This leads to:

- Implicit assumptions
- Scattered validation
- Repeated boundary checks
- Hidden domain rules
- Invalid states possible at runtime

The variable type does not reflect its _true mathematical domain_.

------------------------------------------------------------------------

## 3. The Core Idea

Instead of declaring:

```
int age;
```

We define formally:

Age ∈ [0, 120]

Instead of:

```
string username;
```

We define:

Username ∈ Strings(3..10)

The project was created to model:

Value ∈ Domain

explicitly and formally.

------------------------------------------------------------------------

## 4. What This Project Does

The system separates:

Concept Responsibility

------------ -------------------------------

Domain Defines valid set

Value Holds data

Policy Defines behavior when invalid

Extensions Enable functional composition

This reflects mathematical rigor inside software modeling.

------------------------------------------------------------------------

## 5. Why Not Just Validate?

Traditional validation looks like this:

```
if (age < 0 || age > 120)
    throw new Exception();
```

But this approach:

- Scatters validation across code
- Couples validation to usage
- Allows invalid values to exist temporarily
- Repeats logic in multiple places

Domain modeling centralizes the rule once and for all.

------------------------------------------------------------------------

## 6. Mathematical Thinking Applied to Code

Instead of thinking:

> "This is an int."

We think:

> "This value belongs to a specific mathematical set."

Examples:

- Percentage ∈ \[0, 100\]
- Temperature ∈ \[-50, 150\]
- Latitude ∈ \[-90, 90\]
- Money ∈ \[0, +∞) with scale 2

The project enforces those domains structurally.

------------------------------------------------------------------------

## 7. Benefits Achieved

### 7.1 No Invalid States

You cannot accidentally create:

Age = -10

Percentage = 150

Username = ""

Money = -500

unless the domain allows it.

------------------------------------------------------------------------

### 7.2 Explicit Domain Semantics

The type now expresses intent:

```
DCValue<int> age;
```

means:

age ∈ DefinedDomain

The rule is no longer implicit.

------------------------------------------------------------------------

### 7.3 Reusable Mathematical Domains

Domains become reusable objects:

```
var ageDomain = new NumericDomain<int>(0, 120);
var percentDomain = new NumericDomain<int>(0, 100);
```

Domain logic is not duplicated.

------------------------------------------------------------------------

### 7.4 Functional Composition

Using `Map` and `Bind`, transformations become pipelines:

Raw Input → Domain Validation → Transformation → Output

This mirrors functional mathematical composition.

------------------------------------------------------------------------

## 8. Why This Matters

Primitive obsession is common in software:

- Everything is `int`
- Everything is `string`
- Everything is `decimal`

But real systems have semantics.

By modeling domains explicitly, the code moves closer to:

- Formal reasoning
- Predictability
- Mathematical clarity
- Stronger invariants

------------------------------------------------------------------------

## 9. Money as a Case Study

Money is not:

decimal amount;

It is:

Money ∈ [0, +∞), scale = 2, currency-bound

That is a mathematical structure, not just a primitive.

The project applies domain rigor even to financial modeling.

------------------------------------------------------------------------

## 10. Final Philosophy

This project was written because:

- Primitive types are mathematically too permissive.
- Real-world values belong to constrained sets.
- Domain constraints should be structural, not optional.
- Validation should be centralized.
- Invalid states should be impossible or explicit.

In short:

> Software variables should behave more like mathematical variables.

------------------------------------------------------------------------

Project is her on github:

[https://github.com/vicvondoom/DomainWrapper](https://github.com/vicvondoom/DomainWrapper)

I'm not pretending that something like this doesn't already exist, I hope I've introduced something interesting.

## Similar posts on daily.dev

- [Protect Your Entities with Domain Validation](https://daily.dev/posts/protect-your-entities-with-domain-validation-rha9t8ic8) · Telerik · 3 upvotes · 0 comments
- [What Invariants Are \(and Why a Domain Model Is the Best Place to Enforce Them\)](https://daily.dev/posts/what-invariants-are-and-why-a-domain-model-is-the-best-place-to-enforce-them--jqweafvd0) · Milan Jovanović · 12 upvotes · 0 comments

---

Tags: [#c#](https://daily.dev/tags/c#), [#functional-programming](https://daily.dev/tags/functional-programming), [#domain-driven-design](https://daily.dev/tags/domain-driven-design), [#type-systems](https://daily.dev/tags/type-systems)

[View this post on daily.dev](https://daily.dev/posts/a-domain-wrapper-in-c--krxzntmuh)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"DiscussionForumPosting","mainEntityOfPage":"https://daily.dev/posts/a-domain-wrapper-in-c--krxzntmuh","headline":"A Domain wrapper in C#","text":"A C# library that enforces domain constraints at the type level, inspired by mathematical function domains. Instead of using primitive types like `int` or `string` with implicit validation scattered throughout code, it models values as belonging to explicitly defined mathematical sets (e.g., Age ∈ [0, 120]). The approach centralizes validation logic, prevents invalid states from existing, and enables functional composition through Map/Bind operations. The library separates domain definitions from values and policies, making constraints structural rather than optional.","url":"https://daily.dev/posts/a-domain-wrapper-in-c--krxzntmuh","datePublished":"2026-02-12T13:58:33.773Z","dateModified":"2026-02-12T14:01:16.577Z","author":{"@type":"Person","name":"Dave von Orlando","url":"https://daily.dev/vicvondoom","image":"https://media.daily.dev/image/upload/s---ctTJ_d---/f_auto/v1770905096/avatars/avatar_VNvrMkhAzVZH5ujf0wlCX?_a=BAMAMiiu0","interactionStatistic":{"@type":"InteractionCounter","interactionType":{"@type":"EndorseAction"},"userInteractionCount":560}},"image":"https://media.daily.dev/image/upload/s--Mto2SB5k--/f_auto/v1770904715/posts/KRXzNTmUH?_a=BAMAMiiu0","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"isPartOf":{"@type":"WebPage","url":"https://daily.dev/squads/dotnetsquad","name":".NET"}}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":".NET","item":"https://daily.dev/squads/dotnetsquad"},{"@type":"ListItem","position":3,"name":"A Domain wrapper in C#"}]}
```

