Skip to content

Commit de861a2

Browse files
Add the MediaTypes.EntityFramework library.
1 parent ab6e9f3 commit de861a2

File tree

12 files changed

+362
-39
lines changed

12 files changed

+362
-39
lines changed

PosInformatique.Foundations.slnx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@
4141
<Project Path="src/MediaTypes/MediaTypes.csproj" Id="31039dbf-ee6f-414c-8345-b92a6bc3e60a" />
4242
<Project Path="tests/MediaTypes.Tests/MediaTypes.Tests.csproj" Id="1cee2c26-ceb5-43c8-a5c9-98ced675385c" />
4343
</Folder>
44+
<Folder Name="/MediaTypes/EntityFramework/">
45+
<Project Path="src/MediaTypes.EntityFramework/MediaTypes.EntityFramework.csproj" />
46+
<Project Path="tests/MediaTypes.EntityFramework.Tests/MediaTypes.EntityFramework.Tests.csproj" Id="2b9a0a27-fe1b-4126-adb8-d631b0d2f871" />
47+
</Folder>
4448
<Folder Name="/MediaTypes/Json/">
4549
<Project Path="src/MediaTypes.Json/MediaTypes.Json.csproj" Id="c229cdff-764d-4899-b763-e6b7a866dc2c" />
4650
<Project Path="tests/MediaTypes.Json.Tests/MediaTypes.Json.Tests.csproj" Id="b74c878a-ad2f-470b-82c9-7fe79ecc9ff1" />

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,12 @@ You can install any package using the .NET CLI or NuGet Package Manager.
2424
| |Package | Description | NuGet |
2525
|--|---------|-------------|-------|
2626
|<img src="./src/EmailAddresses/Icon.png" alt="PosInformatique.Foundations.EmailAddresses icon" width="48" height="48" />|[**PosInformatique.Foundations.EmailAddresses**](./src/EmailAddresses/README.md) | Strongly-typed value object representing an email address with validation and normalization as RFC 5322 compliant. | [![NuGet](https://img.shields.io/nuget/v/PosInformatique.Foundations.EmailAddresses)](https://www.nuget.org/packages/PosInformatique.Foundations.EmailAddresses) |
27-
|<img src="./src/EmailAddresses/Icon.png" alt="PosInformatique.Foundations.EmailAddresses.EntityFramework icon" width="48" height="48" />|[**PosInformatique.Foundations.EmailAddresses.EntityFramework**](./src/EmailAddresses.EntityFramework/README.md) | Entity Framework Core integration for the EmailAddress value object, including property configuration and value converter for seamless database persistence. | [![NuGet](https://img.shields.io/nuget/v/PosInformatique.Foundations.EmailAddresses.EntityFramework)](https://www.nuget.org/packages/PosInformatique.Foundations.EmailAddresses.EntityFramework) |
28-
|<img src="./src/EmailAddresses/Icon.png" alt="PosInformatique.Foundations.EmailAddresses.FluentValidation icon" width="48" height="48" />|[**PosInformatique.Foundations.EmailAddresses.FluentValidation**](./src/EmailAddresses.FluentValidation/README.md) | FluentValidation integration for the EmailAddress value object, providing dedicated validators and rules to ensure RFC 5322 compliant email addresses. | [![NuGet](https://img.shields.io/nuget/v/PosInformatique.Foundations.EmailAddresses.FluentValidation)](https://www.nuget.org/packages/PosInformatique.Foundations.EmailAddresses.FluentValidation) |
29-
|<img src="./src/EmailAddresses/Icon.png" alt="PosInformatique.Foundations.EmailAddresses.Json icon" width="48" height="48" />|[**PosInformatique.Foundations.EmailAddresses.Json**](./src/EmailAddresses.Json/README.md) | `System.Text.Json` converter for the EmailAddress value object, enabling seamless serialization and deserialization of RFC 5322 compliant email addresses. | [![NuGet](https://img.shields.io/nuget/v/PosInformatique.Foundations.EmailAddresses.Json)](https://www.nuget.org/packages/PosInformatique.Foundations.EmailAddresses.Json) |
27+
|<img src="./src/EmailAddresses/Icon.png" alt="PosInformatique.Foundations.EmailAddresses.EntityFramework icon" width="48" height="48" />|[**PosInformatique.Foundations.EmailAddresses.EntityFramework**](./src/EmailAddresses.EntityFramework/README.md) | Entity Framework Core integration for the `EmailAddress` value object, including property configuration and value converter for seamless database persistence. | [![NuGet](https://img.shields.io/nuget/v/PosInformatique.Foundations.EmailAddresses.EntityFramework)](https://www.nuget.org/packages/PosInformatique.Foundations.EmailAddresses.EntityFramework) |
28+
|<img src="./src/EmailAddresses/Icon.png" alt="PosInformatique.Foundations.EmailAddresses.FluentValidation icon" width="48" height="48" />|[**PosInformatique.Foundations.EmailAddresses.FluentValidation**](./src/EmailAddresses.FluentValidation/README.md) | FluentValidation integration for the `EmailAddress` value object, providing dedicated validators and rules to ensure RFC 5322 compliant email addresses. | [![NuGet](https://img.shields.io/nuget/v/PosInformatique.Foundations.EmailAddresses.FluentValidation)](https://www.nuget.org/packages/PosInformatique.Foundations.EmailAddresses.FluentValidation) |
29+
|<img src="./src/EmailAddresses/Icon.png" alt="PosInformatique.Foundations.EmailAddresses.Json icon" width="48" height="48" />|[**PosInformatique.Foundations.EmailAddresses.Json**](./src/EmailAddresses.Json/README.md) | `System.Text.Json` converter for the `EmailAddress` value object, enabling seamless serialization and deserialization of RFC 5322 compliant email addresses. | [![NuGet](https://img.shields.io/nuget/v/PosInformatique.Foundations.EmailAddresses.Json)](https://www.nuget.org/packages/PosInformatique.Foundations.EmailAddresses.Json) |
3030
|<img src="./src/MediaTypes/Icon.png" alt="PosInformatique.Foundations.MediaTypes icon" width="48" height="48" />|[**PosInformatique.Foundations.MediaTypes**](./src/MediaTypes/README.md) | Immutable `MimeType` value object with well-known media types and helpers to map between media types and file extensions. | [![NuGet](https://img.shields.io/nuget/v/PosInformatique.Foundations.MediaTypes)](https://www.nuget.org/packages/PosInformatique.Foundations.MediaTypes) |
31-
|<img src="./src/MediaTypes/Icon.png" alt="PosInformatique.Foundations.MediaTypes.Json icon" width="48" height="48" />|[**PosInformatique.Foundations.MediaTypes.Json**](./src/MediaTypes.Json/README.md) | `System.Text.Json` converter for the MimeType value object, enabling seamless serialization and deserialization of MIME types within JSON documents. | [![NuGet](https://img.shields.io/nuget/v/PosInformatique.Foundations.MediaTypes.Json)](https://www.nuget.org/packages/PosInformatique.Foundations.MediaTypes.Json) |
31+
|<img src="./src/MediaTypes/Icon.png" alt="PosInformatique.Foundations.MediaTypes.EntityFramework icon" width="48" height="48" />|[**PosInformatique.Foundations.MediaTypes.EntityFramework**](./src/MediaTypes.EntityFramework/README.md) | Entity Framework Core integration for the `MimeType` value object, including property configuration and value converter for seamless database persistence. | [![NuGet](https://img.shields.io/nuget/v/PosInformatique.Foundations.MediaTypes.EntityFramework)](https://www.nuget.org/packages/PosInformatique.Foundations.MediaTypes.EntityFramework) |
32+
|<img src="./src/MediaTypes/Icon.png" alt="PosInformatique.Foundations.MediaTypes.Json icon" width="48" height="48" />|[**PosInformatique.Foundations.MediaTypes.Json**](./src/MediaTypes.Json/README.md) | `System.Text.Json` converter for the `MimeType` value object, enabling seamless serialization and deserialization of MIME types within JSON documents. | [![NuGet](https://img.shields.io/nuget/v/PosInformatique.Foundations.MediaTypes.Json)](https://www.nuget.org/packages/PosInformatique.Foundations.MediaTypes.Json) |
3233
|<img src="./src/People/Icon.png" alt="PosInformatique.Foundations.People icon" width="48" height="48" />|[**PosInformatique.Foundations.People**](./src/People/README.md) | Strongly-typed value objects for first and last names with validation and normalization. | [![NuGet](https://img.shields.io/nuget/v/PosInformatique.Foundations.People)](https://www.nuget.org/packages/PosInformatique.Foundations.People) |
3334
|<img src="./src/People/Icon.png" alt="PosInformatique.Foundations.People.DataAnnotations icon" width="48" height="48" />|[**PosInformatique.Foundations.People.DataAnnotations**](./src/People.DataAnnotations/README.md) | DataAnnotations attributes for `FirstName` and `LastName` value objects. | [![NuGet](https://img.shields.io/nuget/v/PosInformatique.Foundations.People.DataAnnotations)](https://www.nuget.org/packages/PosInformatique.Foundations.People.DataAnnotations) |
3435
|<img src="./src/People/Icon.png" alt="PosInformatique.Foundations.People.EntityFramework icon" width="48" height="48" />|[**PosInformatique.Foundations.People.EntityFramework**](./src/People.EntityFramework/README.md) | Entity Framework Core integration for `FirstName` and `LastName` value objects, providing fluent property configuration and value converters. | [![NuGet](https://img.shields.io/nuget/v/PosInformatique.Foundations.People.EntityFramework)](https://www.nuget.org/packages/PosInformatique.Foundations.People.EntityFramework) |

src/EmailAddresses.EntityFramework/EmailAddressPropertyExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace Microsoft.EntityFrameworkCore
1111
using PosInformatique.Foundations.EmailAddresses;
1212

1313
/// <summary>
14-
/// Contains extension method to map a <see cref="EmailAddress"/> to a string column.
14+
/// Contains extension methods to map a <see cref="EmailAddress"/> to a string column.
1515
/// </summary>
1616
public static class EmailAddressPropertyExtensions
1717
{
Lines changed: 41 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,82 @@
1-
# PosInformatique.Foundations.EmailAddresses.EntityFramework
1+
# PosInformatique.Foundations.MediaTypes.EntityFramework
22

3-
[![NuGet version](https://img.shields.io/nuget/v/PosInformatique.Foundations.EmailAddresses.EntityFramework)](https://www.nuget.org/packages/PosInformatique.Foundations.EmailAddresses.EntityFramework/)
4-
[![NuGet downloads](https://img.shields.io/nuget/dt/PosInformatique.Foundations.EmailAddresses.EntityFramework)](https://www.nuget.org/packages/PosInformatique.Foundations.EmailAddresses.EntityFramework/)
3+
[![NuGet version](https://img.shields.io/nuget/v/PosInformatique.Foundations.MediaTypes.EntityFramework)](https://www.nuget.org/packages/PosInformatique.Foundations.MediaTypes.EntityFramework/)
4+
[![NuGet downloads](https://img.shields.io/nuget/dt/PosInformatique.Foundations.MediaTypes.EntityFramework)](https://www.nuget.org/packages/PosInformatique.Foundations.MediaTypes.EntityFramework/)
55

66
## Introduction
7-
Provides **Entity Framework Core** integration for the `EmailAddress` value object from
8-
[PosInformatique.Foundations.EmailAddresses](https://www.nuget.org/packages/PosInformatique.Foundations.EmailAddresses/).
9-
This package enables seamless mapping of RFC 5322 compliant email addresses as strongly-typed properties in Entity Framework Core entities.
107

11-
It ensures proper SQL type mapping, validation, and conversion to `VARCHAR` when persisted to the database.
8+
Provides **Entity Framework Core** integration for the `MimeType` value object from
9+
[PosInformatique.Foundations.MediaTypes](https://www.nuget.org/packages/PosInformatique.Foundations.MediaTypes/).
10+
This package enables seamless mapping of MIME types as strongly-typed properties in Entity Framework Core entities.
11+
12+
It ensures proper SQL type mapping, validation, and conversion to `VARCHAR(128)` when persisted to the database.
1213

1314
## Install
15+
1416
You can install the package from NuGet:
1517

1618
```powershell
17-
dotnet add package PosInformatique.Foundations.EmailAddresses.EntityFramework
19+
dotnet add package PosInformatique.Foundations.MediaTypes.EntityFramework
1820
```
1921

20-
This package depends on the base package [PosInformatique.Foundations.EmailAddresses](https://www.nuget.org/packages/PosInformatique.Foundations.EmailAddresses/).
22+
This package depends on the base package [PosInformatique.Foundations.MediaTypes](https://www.nuget.org/packages/PosInformatique.Foundations.MediaTypes/).
2123

2224
## Features
23-
- Provides an extension method `IsEmailAddress()` to configure EF Core properties for `EmailAddress`.
24-
- Maps to `VARCHAR(320)` database columns using the SQL type `EmailAddress` (you must define the SQL type `EmailAddress` mapped to `VARCHAR(320)` in your database).
25-
- Ensures validation, normalization, and safe conversion to/from database fields.
26-
- Built on top of the core `EmailAddress` value object.
25+
26+
- Provides an extension method `IsMimeType()` to configure EF Core properties for `MimeType`.
27+
- Maps to `VARCHAR(128)` database columns using the SQL type `MimeType` (you must define the SQL type `MimeType` mapped to `VARCHAR(128)` in your database).
28+
- Ensures validation and safe conversion to/from database fields.
29+
- Built on top of the core `MimeType` value object.
2730

2831
## Use cases
29-
- **Entity mapping**: enforce strong typing for email addresses at the persistence layer.
30-
- **Consistency**: ensure the same validation rules are applied in your entities and database.
31-
- **Safety**: prevent invalid strings being stored in your database
32+
33+
- **Entity mapping**: enforce strong typing for MIME types at the persistence layer.
34+
- **Consistency**: ensure the same rules are applied in your entities and database.
35+
- **Safety**: prevent invalid or malformed MIME type strings being stored in your database.
3236

3337
## Examples
3438

35-
> ⚠️ To use `IsEmailAddress()`, you must first define the SQL type `EmailAddress` mapped to `VARCHAR(320)` in your database.
36-
For SQL Server, you can create it with:
39+
> ⚠️ To use `IsMimeType()`, you must first define the SQL type `MimeType` mapped to `VARCHAR(128)` in your database.
40+
> For SQL Server, you can create it with:
3741
3842
```sql
39-
CREATE TYPE EmailAddress FROM VARCHAR(320) NOT NULL;
43+
CREATE TYPE MimeType FROM VARCHAR(128) NOT NULL;
4044
```
4145

4246
### Example: Configure an entity
47+
4348
```csharp
4449
using Microsoft.EntityFrameworkCore;
45-
using PosInformatique.Foundations;
50+
using PosInformatique.Foundations.MediaTypes;
4651

47-
public class User
52+
public class Document
4853
{
4954
public int Id { get; set; }
50-
public EmailAddress Email { get; set; }
55+
56+
public MimeType ContentType { get; set; }
5157
}
5258

5359
public class ApplicationDbContext : DbContext
5460
{
55-
public DbSet<User> Users => Set<User>();
61+
public DbSet<Document> Documents => Set<Document>();
5662

5763
protected override void OnModelCreating(ModelBuilder modelBuilder)
5864
{
59-
modelBuilder.Entity<User>()
60-
.Property(u => u.Email)
61-
.IsEmailAddress();
65+
modelBuilder.Entity<Document>()
66+
.Property(d => d.ContentType)
67+
.IsMimeType();
6268
}
6369
}
6470
```
6571

66-
This will configure the `Email` property of the `User` entity with:
67-
- `VARCHAR(320)` (Non-unicode) column length
68-
- SQL column type `EmailAddress`
72+
This will configure the `ContentType` property of the `Document` entity with:
73+
74+
- `VARCHAR(128)` (non-unicode) column length
75+
- SQL column type `MimeType`
76+
- Proper conversion between `MimeType` and `string`
6977

7078
## Links
71-
- [NuGet package: EmailAddresses.EntityFramework](https://www.nuget.org/packages/PosInformatique.Foundations.EmailAddresses.EntityFramework/)
72-
- [NuGet package: EmailAddresses (core library)](https://www.nuget.org/packages/PosInformatique.Foundations.EmailAddresses/)
73-
- [Source code](https://github.com/PosInformatique/PosInformatique.Foundations)
79+
80+
- [NuGet package: MediaTypes.EntityFramework](https://www.nuget.org/packages/PosInformatique.Foundations.MediaTypes.EntityFramework/)
81+
- [NuGet package: MediaTypes (core library)](https://www.nuget.org/packages/PosInformatique.Foundations.MediaTypes/)
82+
- [Source code](https://github.com/PosInformatique/PosInformatique.Foundations)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
1.0.0
2+
- Initial release with the support Entity Framework persitance for MimeType value object.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<IsPackable>true</IsPackable>
5+
6+
<Description>
7+
Provides Entity Framework Core integration for the MimeType value object.
8+
Enables seamless mapping of MIME types as strongly-typed properties in Entity Framework Core entities, with safe conversion to string.
9+
</Description>
10+
<PackageTags>mimetype;media;mediatype;contenttype;entityframework;efcore;valueobject;validation;mapping;conversion;dotnet;posinformatique</PackageTags>
11+
<PackageReleaseNotes>
12+
$([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/CHANGELOG.md"))
13+
</PackageReleaseNotes>
14+
15+
</PropertyGroup>
16+
17+
<ItemGroup>
18+
<ProjectReference Include="..\..\src\MediaTypes\MediaTypes.csproj" />
19+
</ItemGroup>
20+
21+
<ItemGroup>
22+
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" />
23+
</ItemGroup>
24+
25+
<ItemGroup>
26+
<Content Include="CHANGELOG.md" Pack="false" />
27+
<Content Include="..\MediaTypes\Icon.png" Pack="true" PackagePath="" />
28+
<Content Include="README.md" Pack="true" PackagePath="" />
29+
</ItemGroup>
30+
31+
</Project>
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//-----------------------------------------------------------------------
2+
// <copyright file="MimeTypePropertyExtensions.cs" company="P.O.S Informatique">
3+
// Copyright (c) P.O.S Informatique. All rights reserved.
4+
// </copyright>
5+
//-----------------------------------------------------------------------
6+
7+
namespace Microsoft.EntityFrameworkCore
8+
{
9+
using Microsoft.EntityFrameworkCore.Metadata.Builders;
10+
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
11+
using PosInformatique.Foundations.MediaTypes;
12+
13+
/// <summary>
14+
/// Contains extension methods to map a <see cref="MimeType"/> to a string column.
15+
/// </summary>
16+
public static class MimeTypePropertyExtensions
17+
{
18+
/// <summary>
19+
/// Configures the specified <paramref name="property"/> to be mapped on a column with a SQL <c>MimeType</c> type.
20+
/// The <c>MimeType</c> type must be mapped to a <c>VARCHAR(128)</c>.
21+
/// </summary>
22+
/// <typeparam name="T">Type of the property which must be <see cref="MimeType"/>.</typeparam>
23+
/// <param name="property">Entity property to map in the <see cref="ModelBuilder"/>.</param>
24+
/// <returns>The <paramref name="property"/> instance to configure the configuration of the property.</returns>
25+
/// <exception cref="ArgumentNullException">If the specified <paramref name="property"/> argument is <see langword="null"/>.</exception>
26+
/// <exception cref="ArgumentException">If the specified <typeparamref name="T"/> generic type is not a <see cref="MimeType"/>.</exception>
27+
public static PropertyBuilder<T> IsMimeType<T>(this PropertyBuilder<T> property)
28+
{
29+
ArgumentNullException.ThrowIfNull(property);
30+
31+
if (typeof(T) != typeof(MimeType))
32+
{
33+
throw new ArgumentException($"The '{nameof(IsMimeType)}()' method must be called on '{nameof(MimeType)} class.", nameof(property));
34+
}
35+
36+
return property
37+
.IsUnicode(false)
38+
.HasMaxLength(128)
39+
.HasColumnType("MimeType")
40+
.HasConversion(MimeTypeConverter.Instance);
41+
}
42+
43+
private sealed class MimeTypeConverter : ValueConverter<MimeType, string>
44+
{
45+
private MimeTypeConverter()
46+
: base(mimeType => mimeType.ToString(), @string => MimeType.Parse(@string))
47+
{
48+
}
49+
50+
public static MimeTypeConverter Instance { get; } = new MimeTypeConverter();
51+
}
52+
}
53+
}

0 commit comments

Comments
 (0)