Facet.Extensions
2.1.0
See the version list below for details.
dotnet add package Facet.Extensions --version 2.1.0
NuGet\Install-Package Facet.Extensions -Version 2.1.0
<PackageReference Include="Facet.Extensions" Version="2.1.0" />
<PackageVersion Include="Facet.Extensions" Version="2.1.0" />
<PackageReference Include="Facet.Extensions" />
paket add Facet.Extensions --version 2.1.0
#r "nuget: Facet.Extensions, 2.1.0"
#:package Facet.Extensions@2.1.0
#addin nuget:?package=Facet.Extensions&version=2.1.0
#tool nuget:?package=Facet.Extensions&version=2.1.0
<div align="center"> <img src="https://raw.githubusercontent.com/Tim-Maes/Facet/master/assets/Facet.png" alt="Facet logo" width="400"> </div>
<div align="center"> "One part of a subject, situation, object that has many parts." </div>
Facet is a C# source generator that lets you define lightweight projections (DTOs, API models, etc.) directly from your domain models, without writing boilerplate.
It generates partial classes, records, structs, or record structs with constructors, optional LINQ projections, and even supports custom mappings, all at compile time, with zero runtime cost.
💎 What is Facetting?
Facetting is the process of defining focused views of a larger model at compile time.
Instead of manually writing separate DTOs, mappers, and projections, Facet allows you to declare what you want to keep, and generates everything else.
You can think of it like carving out a specific facet of a gem:
- The part you care about
- Leaving the rest behind.
❔ Why Facetting?
- Reduce duplication across DTOs, projections, and ViewModels
- Maintain strong typing with no runtime cost
- Stay DRY (Don't Repeat Yourself) without sacrificing performance
- Works seamlessly with LINQ providers like Entity Framework
📋 Documentation
⭐ Key Features
- ✅ Generate classes, records, structs, or record structs from existing types
- ✅ Exclude fields/properties you don't want (create a Facetted view of your model)
- ✅ Include/redact public fields
- ✅ Auto-generate constructors for fast mapping
- ✅ LINQ projection expressions
(Expression<Func<TSource,TTarget>>)
- ✅ Full mapping support with custom mapping configurations
🌎 The Facet Ecosystem
Facet is modular and consists of several NuGet packages:
Facet: The core source generator. Generates DTOs, projections, and mapping code.
Facet.Extensions: Provider-agnostic extension methods for mapping and projecting (works with any LINQ provider, no EF Core dependency).
Facet.Extensions.EFCore: Async extension methods for Entity Framework Core (requires EF Core 6+).
Facet.Mapping: Advanced static mapping configuration support with async capabilities and dependency injection for complex mapping scenarios.
🚀 Quick start
Install the NuGet Package
dotnet add package Facet
For LINQ helpers:
dotnet add package Facet.Extensions
For EF Core support:
dotnet add package Facet.Extensions.EFCore
Basic Projection
[Facet(typeof(User))]
public partial class UserDto { }
// Auto-generates constructor, properties, and LINQ projection
var userDto = user.ToFacet<User, UserDto>();
var userDtos = users.SelectFacets<User, UserDto>();
Custom Sync Mapping
public class UserMapper : IFacetMapConfiguration<User, UserDto>
{
public static void Map(User source, UserDto target)
{
target.FullName = $"{source.FirstName} {source.LastName}";
}
}
[Facet(typeof(User), Configuration = typeof(UserMapper))]
public partial class UserDto
{
public string FullName { get; set; }
}
Async Mapping for I/O Operations
public class UserAsyncMapper : IFacetMapConfigurationAsync<User, UserDto>
{
public static async Task MapAsync(User source, UserDto target, CancellationToken cancellationToken = default)
{
// Async database lookup
target.ProfilePicture = await GetProfilePictureAsync(source.Id, cancellationToken);
// Async API call
target.ReputationScore = await CalculateReputationAsync(source.Email, cancellationToken);
}
}
// Usage
var userDto = await user.ToFacetAsync<User, UserDto, UserAsyncMapper>();
var userDtos = await users.ToFacetsParallelAsync<User, UserDto, UserAsyncMapper>();
Async Mapping with Dependency Injection
public class UserAsyncMapperWithDI : IFacetMapConfigurationAsyncInstance<User, UserDto>
{
private readonly IProfilePictureService _profileService;
private readonly IReputationService _reputationService;
public UserAsyncMapperWithDI(IProfilePictureService profileService, IReputationService reputationService)
{
_profileService = profileService;
_reputationService = reputationService;
}
public async Task MapAsync(User source, UserDto target, CancellationToken cancellationToken = default)
{
// Use injected services
target.ProfilePicture = await _profileService.GetProfilePictureAsync(source.Id, cancellationToken);
target.ReputationScore = await _reputationService.CalculateReputationAsync(source.Email, cancellationToken);
}
}
// Usage with DI
var mapper = new UserAsyncMapperWithDI(profileService, reputationService);
var userDto = await user.ToFacetAsync(mapper);
var userDtos = await users.ToFacetsParallelAsync(mapper);
EF Core Integration
// Async projection directly in EF Core queries
var userDtos = await dbContext.Users
.Where(u => u.IsActive)
.ToFacetsAsync<User, UserDto>();
Facet — Define less, project more.
Product | Versions 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 is compatible. 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. |
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Facet.Extensions:
Package | Downloads |
---|---|
Facet.Extensions.EFCore
EF Core async extension methods for Facet. |
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last Updated |
---|---|---|
2.6.1 | 0 | 9/10/2025 |
2.6.0 | 41 | 9/9/2025 |
2.5.0 | 221 | 9/4/2025 |
2.4.8 | 163 | 9/3/2025 |
2.4.7 | 202 | 9/1/2025 |
2.4.6 | 128 | 9/1/2025 |
2.4.5 | 189 | 8/30/2025 |
2.4.4 | 317 | 8/27/2025 |
2.4.3 | 180 | 8/27/2025 |
2.4.2 | 176 | 8/27/2025 |
2.4.0 | 204 | 8/26/2025 |
2.3.0 | 1,427 | 8/20/2025 |
2.2.0 | 155 | 8/20/2025 |
2.1.0 | 259 | 8/18/2025 |
2.0.1 | 576 | 8/5/2025 |
2.0.0 | 147 | 8/4/2025 |
1.9.3 | 132 | 7/4/2025 |
1.8.0 | 161 | 6/4/2025 |
1.7.0 | 201 | 5/6/2025 |
1.6.0 | 145 | 4/27/2025 |
1.5.0 | 170 | 4/27/2025 |