{"id":22504896,"url":"https://github.com/whatishedoing/whatishedoing.domainmodels","last_synced_at":"2025-07-18T16:06:41.818Z","repository":{"id":27338478,"uuid":"113498568","full_name":"WhatIsHeDoing/WhatIsHeDoing.DomainModels","owner":"WhatIsHeDoing","description":"A library of domain models for .NET.","archived":false,"fork":false,"pushed_at":"2023-02-21T20:57:49.000Z","size":361,"stargazers_count":4,"open_issues_count":11,"forks_count":1,"subscribers_count":1,"default_branch":"live","last_synced_at":"2025-06-30T16:51:40.434Z","etag":null,"topics":["domain-driven-design","domain-model","dotnet","nuget-package","serialization"],"latest_commit_sha":null,"homepage":"https://www.nuget.org/packages/WhatIsHeDoing.DomainModels/","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/WhatIsHeDoing.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-12-07T21:06:40.000Z","updated_at":"2021-11-14T20:01:23.000Z","dependencies_parsed_at":"2023-02-14T11:01:40.521Z","dependency_job_id":null,"html_url":"https://github.com/WhatIsHeDoing/WhatIsHeDoing.DomainModels","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/WhatIsHeDoing/WhatIsHeDoing.DomainModels","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WhatIsHeDoing%2FWhatIsHeDoing.DomainModels","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WhatIsHeDoing%2FWhatIsHeDoing.DomainModels/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WhatIsHeDoing%2FWhatIsHeDoing.DomainModels/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WhatIsHeDoing%2FWhatIsHeDoing.DomainModels/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/WhatIsHeDoing","download_url":"https://codeload.github.com/WhatIsHeDoing/WhatIsHeDoing.DomainModels/tar.gz/refs/heads/live","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WhatIsHeDoing%2FWhatIsHeDoing.DomainModels/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264752787,"owners_count":23658714,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["domain-driven-design","domain-model","dotnet","nuget-package","serialization"],"created_at":"2024-12-07T00:11:04.717Z","updated_at":"2025-07-11T07:05:12.051Z","avatar_url":"https://github.com/WhatIsHeDoing.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# WhatIsHeDoing.DomainModels\r\n\r\n[![NuGet package](https://img.shields.io/nuget/v/WhatIsHeDoing.DomainModels.svg)][NuGet]\r\n[![NuGet downloads](https://img.shields.io/nuget/dt/WhatIsHeDoing.DomainModels.svg)][NuGet]\r\n[![AppVeyor Windows build status](https://ci.appveyor.com/api/projects/status/52xl0ifv8cfgjj4a?svg=true)][appveyor]\r\n[![Codecov code coverage](https://codecov.io/gh/WhatIsHeDoing/WhatIsHeDoing.DomainModels/branch/master/graph/badge.svg)](https://codecov.io/gh/WhatIsHeDoing/WhatIsHeDoing.DomainModels)\r\n[![Travis CI Linux build Status](https://travis-ci.org/WhatIsHeDoing/WhatIsHeDoing.DomainModels.svg)][Travis]\r\n[![Codenvy workspace](https://codenvy.io/factory/resources/codenvy-contribute.svg)][factory]\r\n\r\nA library of domain models for .NET.\r\n\r\n## 👋 Introduction\r\n\r\nAs the [Wikipedia] article explains:\r\n\r\n\u003e A domain model is a system of abstractions that describes select aspects of a sphere of knowledge, influence,\r\n\u003e or activity (a domain). The model can then be used to solve problems related to that domain. The domain model\r\n\u003e is a representation of meaningful real-world concepts pertinent to the domain that need to be modelled in software.\r\n\u003e The concepts include the data involved in the business and rules the business uses in relation to that data.\r\n\r\nThe domain models in this library implement a contract that ensures they are validated, serialised and\r\ndeserialised, in a consistent manner.\r\n\r\n**Note**: these models only _validate_ their values, they do not _verify_ them. That is, a model value\r\ncan be in the correct format, but it might not exist! You may still need to use another means to verify them,\r\nsuch as calling a service. For example, the UK postcode `SE1 9XX` is valid, but it does not [exist][Royal Mail].\r\n\r\n## 📡 Demo\r\n\r\nSee how the Swagger demo site - use `dotnet run --project WhatIsHeDoing.DomainModels.APITest` -\r\nhandles URL, JSON and XML domain model de/serialisation.\r\n\r\n![Web API](WhatIsHeDoing.DomainModels.APITest/swagger.png)\r\n\r\n## 🦮 Usage\r\n\r\n### Installing\r\n\r\nThis package is available via [NuGet], and targets .NET Core 2.2 for cross-platform use.\r\n\r\n### The Models\r\n\r\n#### Barcodes\r\n\r\n* `EAN`: [International Article Number][EAN]\r\n* `ISBN`: [International Standard Book Number][ISBN]\r\n\r\n#### Locations\r\n\r\n* `CountryCode`: [two][cc1] and [three][cc2]-letter country codes.\r\n* `UKPostcode`: United Kingdom [postcode]\r\n\r\n## An Example\r\n\r\nLet's say you are capturing the address of user in the United Kingdom in a web form, and posting it\r\nto a .NET Web API. The postcode is a mix of alphanumeric characters, often separated by a space, so\r\nwhy not simply use a `string`?\r\n\r\n```C#\r\npublic class Address\r\n{\r\n    public string Line1 { get; set; }\r\n    public string Line2 { get; set; }\r\n    public string Town { get; set; }\r\n    public string Country { get; set; }\r\n    public string Postcode { get; set; }\r\n}\r\n```\r\n\r\n### The Problems\r\n\r\nWhilst a postcode looks simple enough, it is comprised of multiple different components, and is validated by a\r\nsurprisingly complex regular expression. If it is stored as a `string`, when is it validated, and where does\r\nthat logic reside? If it is passed to a Web API, you could add a model annotation, but what about other scenarios,\r\nsuch as console and mobile apps? What happens when we need to access only parts of that postcode, such as\r\nthe postcode area, which could be used to determine whether the user is based in [Northern Ireland][postcodes]?\r\n\r\n### Using a Domain Model\r\n\r\nCapturing the same information in a domain model is as simple as switching to the `UKPostcode` type:\r\n\r\n```C#\r\npublic class Address\r\n{\r\n    // As before, but now:\r\n    public UKPostcode Postcode { get; set; }\r\n}\r\n```\r\n\r\nNow, when the data is passed to the service, we can check the `ModelState` as usual, before moving on:\r\n\r\n```C#\r\nnamespace Test\r\n{\r\n    using Microsoft.AspNetCore.Mvc;\r\n    using Models;\r\n    using System.Net;\r\n    using WhatIsHeDoing.DomainModels.Locations;\r\n\r\n    [Route(\"api/[controller]\")]\r\n    public class UserDetailsController : Controller\r\n    {\r\n        /// \u003csummary\u003e\r\n        /// Does something useful with an address.\r\n        /// \u003c/summary\u003e\r\n        /// \u003cparam name=\"address\"\u003eAddress to use\u003c/param\u003e\r\n        /// \u003creturns\u003eSuccess\u003c/returns\u003e\r\n        [HttpPost]\r\n        [ProducesResponseType(typeof(string), (int)HttpStatusCode.OK)]\r\n        [ProducesResponseType((int)HttpStatusCode.BadRequest)]\r\n        public IActionResult Post(Address address) =\u003e ModelState.IsValid\r\n            ? Ok(address.Postcode.PostcodeArea)\r\n            : (ActionResult)new BadRequestResult();\r\n    }\r\n}\r\n```\r\n\r\nThis works for both JSON (using [Json.NET]) and XML serialisation.\r\n\r\nThe underlying `Value` type is a `string`, and the model provides an implicit string operator override,\r\nas you can see from unit tests like this from the `WhatIsHeDoing.DomainModels.Test` project:\r\n\r\n```C#\r\n[Fact]\r\npublic void StringFormat()\r\n{\r\n    var postcode = new UKPostcode(\"SW1 1AA\");\r\n    var actual = $\"Hello from {postcode}!\";\r\n    Assert.Equal(\"Hello from SW1 1AA!\", actual);\r\n}\r\n```\r\n\r\n## 🆘 Contributing\r\n\r\nAll contributions are greatly welcomed! Please see the [contributing] guide for more information.\r\n\r\nIf you are developing locally, pull down this repo and build within Visual Studio (any edition), or\r\nrun `dotnet test` on any platform; the `master` branch is continuously built on both [Windows][appveyor]\r\nand [Linux][Travis]. Alternatively, simply create a new Codenvy workspace from my [factory]!\r\nYou can even run the API test project by simply using the `Run` :arrow_forward: feature; just click the\r\ndynamic `preview` URL it generates in the terminal.\r\n\r\n![Codenvy workspace](Codenvy-WhatIsHeDoing-NuGet.png)\r\n\r\n## 👱 Authors\r\n\r\n* **Darren Hickling**: \u003chttps://darrenhickling.com/\u003e\r\n\r\n[appveyor]: https://ci.appveyor.com/project/DarrenHickling/whatishedoing-domainmodels-j4bij\r\n    \"WhatIsHeDoing.DomainModels - AppVeyor [Windows build]\"\r\n[cc1]: https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2\r\n[cc2]: https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3\r\n[contributing]: CONTRIBUTING.md\r\n[EAN]: https://en.wikipedia.org/wiki/International_Article_Number\r\n[factory]: https://codenvy.io/f?id=factorydoivwyk603gvrx9x \"Start development on Codenvy\"\r\n[ISBN]: https://en.wikipedia.org/wiki/International_Standard_Book_Number\r\n[Json.NET]: https://www.newtonsoft.com/json\r\n[NuGet]: https://www.nuget.org/packages/WhatIsHeDoing.DomainModels/\r\n[postcode]: http://en.wikipedia.org/wiki/Postcodes_in_the_United_Kingdom\r\n[postcodes]: https://www.townscountiespostcodes.co.uk/postcodes-in-northern-ireland/\r\n    \"Postcodes in Northern Ireland | Northern Ireland Postcode Information, UK\"\r\n[Royal Mail]: https://www.royalmail.com/find-a-postcode \"Postcode Finder - Find an Address | Royal Mail Group Ltd\"\r\n[Travis]: https://travis-ci.org/WhatIsHeDoing/WhatIsHeDoing.DomainModels\r\n    \"WhatIsHeDoing/WhatIsHeDoing.DomainModels - Travis CI [Linux build]\"\r\n[Wikipedia]: https://en.wikipedia.org/wiki/Domain_model\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwhatishedoing%2Fwhatishedoing.domainmodels","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwhatishedoing%2Fwhatishedoing.domainmodels","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwhatishedoing%2Fwhatishedoing.domainmodels/lists"}