WhatIsHeDoing.DomainModels 8.0.0

dotnet add package WhatIsHeDoing.DomainModels --version 8.0.0
                    
NuGet\Install-Package WhatIsHeDoing.DomainModels -Version 8.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="WhatIsHeDoing.DomainModels" Version="8.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="WhatIsHeDoing.DomainModels" Version="8.0.0" />
                    
Directory.Packages.props
<PackageReference Include="WhatIsHeDoing.DomainModels" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add WhatIsHeDoing.DomainModels --version 8.0.0
                    
#r "nuget: WhatIsHeDoing.DomainModels, 8.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package WhatIsHeDoing.DomainModels@8.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=WhatIsHeDoing.DomainModels&version=8.0.0
                    
Install as a Cake Addin
#tool nuget:?package=WhatIsHeDoing.DomainModels&version=8.0.0
                    
Install as a Cake Tool

WhatIsHeDoing.DomainModels

NuGet package NuGet downloads build

A library of domain models for .NET.

👋 Introduction

As the Wikipedia article explains:

A domain model is a system of abstractions that describes select aspects of a sphere of knowledge, influence, or activity (a domain). The model can then be used to solve problems related to that domain. The domain model is a representation of meaningful real-world concepts pertinent to the domain that need to be modelled in software. The concepts include the data involved in the business and rules the business uses in relation to that data.

The domain models in this library implement a contract that ensures they are validated, serialised and deserialised, in a consistent manner.

Note: these models only validate their values, they do not verify them. That is, a model value can be in the correct format, but it might not exist! You may still need to use another means to verify them, such as calling a service. For example, the UK postcode SE1 9XX is valid, but it does not exist.

📡 Demo

Run just api to see how the Swagger demo site handles URL, JSON and XML domain model de/serialisation.

Web API

🦮 Usage

Installing

This package is available via NuGet and targets .NET 8 for cross-platform use.

The Models

Barcodes
Locations
  • CountryCode: two and three-letter country codes.
  • UKPostcode: United Kingdom postcode

An Example

Let's say you are capturing the address of user in the United Kingdom in a web form, and posting it to a .NET Web API. The postcode is a mix of alphanumeric characters, often separated by a space, so why not simply use a string?

public class Address
{
    public string Line1 { get; set; }
    public string Line2 { get; set; }
    public string Town { get; set; }
    public string Country { get; set; }
    public string Postcode { get; set; }
}

The Problems

Whilst a postcode looks simple enough, it is comprised of multiple different components, and is validated by a surprisingly complex regular expression. If it is stored as a string, when is it validated, and where does that logic reside? If it is passed to a Web API, you could add a model annotation, but what about other scenarios, such as console and mobile apps? What happens when we need to access only parts of that postcode, such as the postcode area, which could be used to determine whether the user is based in Northern Ireland?

Using a Domain Model

Capturing the same information in a domain model is as simple as switching to the UKPostcode type:

public class Address
{
    // As before, but now:
    public UKPostcode Postcode { get; set; }
}

Now, when the data is passed to the service, we can check the ModelState as usual, before moving on:

namespace Test
{
    using Microsoft.AspNetCore.Mvc;
    using Models;
    using System.Net;
    using WhatIsHeDoing.DomainModels.Locations;

    [Route("api/[controller]")]
    public class UserDetailsController : Controller
    {
        /// <summary>
        /// Does something useful with an address.
        /// </summary>
        /// <param name="address">Address to use</param>
        /// <returns>Success</returns>
        [HttpPost]
        [ProducesResponseType(typeof(string), (int)HttpStatusCode.OK)]
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
        public IActionResult Post(Address address) => ModelState.IsValid
            ? Ok(address.Postcode.PostcodeArea)
            : (ActionResult)new BadRequestResult();
    }
}

This works for both JSON (using Json.NET) and XML serialisation.

The underlying Value type is a string, and the model provides an implicit string operator override, as you can see from unit tests like this from the WhatIsHeDoing.DomainModels.Test project:

[Fact]
public void StringFormat()
{
    var postcode = new UKPostcode("SW1 1AA");
    var actual = $"Hello from {postcode}!";
    Assert.Equal("Hello from SW1 1AA!", actual);
}

🆘 Contributing

All contributions are greatly welcomed! Please see the contributing guide for more information.

If you are developing locally, pull down this repo and build within Visual Studio (any edition), or run dotnet test on any platform; the live branch is continuously built using the GitHub Action.

👱 Authors

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
8.0.0 175 10/28/2025
5.0.1 632 9/22/2021
5.0.0 502 9/22/2021
4.1.0 571 5/1/2021
4.0.0 589 11/11/2020
3.0.0 772 8/1/2019
2.4.0 1,539 12/10/2017
2.3.0 1,497 12/9/2017
2.2.1 1,445 12/7/2017
2.2.0 1,452 12/7/2017
2.1.0 1,498 12/6/2017
2.0.0 1,446 12/5/2017
1.1.0 1,285 11/23/2017
1.0.6 1,189 11/20/2017
1.0.5 1,159 11/20/2017
1.0.0 2,153 7/12/2015

Upgrading latest Core package