Refbesh.CastBesh
1.0.1
dotnet add package Refbesh.CastBesh --version 1.0.1
NuGet\Install-Package Refbesh.CastBesh -Version 1.0.1
<PackageReference Include="Refbesh.CastBesh" Version="1.0.1" />
<PackageVersion Include="Refbesh.CastBesh" Version="1.0.1" />
<PackageReference Include="Refbesh.CastBesh" />
paket add Refbesh.CastBesh --version 1.0.1
#r "nuget: Refbesh.CastBesh, 1.0.1"
#:package Refbesh.CastBesh@1.0.1
#addin nuget:?package=Refbesh.CastBesh&version=1.0.1
#tool nuget:?package=Refbesh.CastBesh&version=1.0.1
CastBesh
CastBesh is a high-performance object mapping library that brings native C# cast syntax to complex type transformations. Map objects as naturally as casting primitives!
🚀 Why CastBesh?
Transform this verbose mapping:
var dto = mapper.Map<UserEntity, UserDto>(userEntity);
Into this elegant, native C# syntax:
var dto = (UserDto)userEntity; // Just like (int)myDouble!
One simple line per cast direction - that's all it takes!
✨ Features
- Native Cast Syntax: Use explicit cast operators
(TargetType)sourcejust like primitive types - One-Line Setup: Add one simple cast operator per direction - done!
- High Performance: Expression tree compilation (10-50x faster than reflection)
- Multi-Framework: Supports .NET 6, 7, 8, and 9
- Fluent Configuration: Easy-to-use configuration API
- Async Support: Built-in asynchronous mapping capabilities
- Collection Mapping: Optimized batch operations for collections
- Alternative Syntax:
.As<T>()extension method when you can't modify types - Type Safety: Compile-time type checking
- Zero Reflection: Compiled mappers for maximum speed
📦 Installation
dotnet add package Refbesh.CastBesh
Or via NuGet Package Manager:
Install-Package Refbesh.CastBesh
🎯 Quick Start
1. Define Your Models with Cast Operators
Add one line per cast direction to your classes:
using Refbesh.CastBesh.Casting;
public class UserEntity
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public bool IsActive { get; set; }
// Add cast operator - just one line!
public static explicit operator UserDto(UserEntity source)
=> CastEngine.Cast<UserEntity, UserDto>(source);
}
public class UserDto
{
public int Id { get; set; }
public string FullName { get; set; }
public string Email { get; set; }
public string Status { get; set; }
}
2. Configure Mappings (Startup)
using Refbesh.CastBesh;
CastBeshStartup.Configure(config =>
{
config.CreateMap<UserEntity, UserDto>()
.WithSync(entity => new UserDto
{
Id = entity.Id,
FullName = $"{entity.FirstName} {entity.LastName}",
Email = entity.Email,
Status = entity.IsActive ? "Active" : "Inactive"
})
.Build();
});
3. Use Native Cast Syntax Anywhere!
var userEntity = new UserEntity
{
Id = 1,
FirstName = "John",
LastName = "Doe",
Email = "john@example.com",
IsActive = true
};
// Cast like a primitive type!
var userDto = (UserDto)userEntity;
Console.WriteLine(userDto.FullName); // "John Doe"
Console.WriteLine(userDto.Status); // "Active"
📚 Usage Examples
Bidirectional Mapping
public class UserEntity
{
// Properties...
public static explicit operator UserDto(UserEntity source)
=> CastEngine.Cast<UserEntity, UserDto>(source);
}
public class UserDto
{
// Properties...
// Reverse cast
public static explicit operator UserEntity(UserDto source)
=> CastEngine.Cast<UserDto, UserEntity>(source);
}
// Usage - works both ways!
var dto = (UserDto)entity;
var entity = (UserEntity)dto;
Multiple Target Types
public class UserEntity
{
// Properties...
// Cast to multiple types
public static explicit operator UserDto(UserEntity source)
=> CastEngine.Cast<UserEntity, UserDto>(source);
public static explicit operator UserListDto(UserEntity source)
=> CastEngine.Cast<UserEntity, UserListDto>(source);
}
// Usage
var fullDto = (UserDto)userEntity;
var listDto = (UserListDto)userEntity;
Collection Mapping
var entities = new List<UserEntity> { /* ... */ };
// Option 1: LINQ with cast syntax
var dtos = entities.Select(e => (UserDto)e).ToList();
// Option 2: Optimized extension method
var dtos = entities.CastToList<UserEntity, UserDto>();
Inline Casting in Methods
public void ProcessUser(UserDto dto)
{
Console.WriteLine($"Processing: {dto.FullName}");
}
// Cast inline in method calls - just like primitives!
ProcessUser((UserDto)userEntity);
LINQ Integration
var activeDtos = users
.Where(u => u.IsActive)
.Select(u => (UserDto)u)
.OrderBy(d => d.FullName)
.ToList();
Async Mapping
// Configure with async support
config.CreateMap<UserEntity, UserDto>()
.WithSync(entity => /* sync mapping */)
.WithAsync(async (entity, ct) =>
{
await Task.Delay(10, ct); // Simulate async work
return new UserDto { /* ... */ };
})
.Build();
// Use async casting
var dto = await CastEngine.CastAsync<UserEntity, UserDto>(userEntity);
Alternative Syntax (When You Can't Modify Types)
If you can't add cast operators to a type (e.g., third-party library), use extension methods:
using Refbesh.CastBesh.Extensions;
// Use .As<T>() extension method
var dto = userEntity.As<UserDto>();
// Or fluent syntax
var dto = userEntity.ToCastable().To<UserDto>();
// Safe casting
if (userEntity.TryAs<UserDto>(out var dto))
{
Console.WriteLine($"Success: {dto.FullName}");
}
🔧 Advanced Features
Custom Mappers
public class CustomUserMapper : CastMapperBase<UserEntity, UserDto>
{
public override UserDto Map(UserEntity source)
{
// Custom mapping logic
return new UserDto { /* ... */ };
}
}
config.RegisterMapper(new CustomUserMapper());
Auto-Mapping (Convention-Based)
For simple property-to-property mappings:
using Refbesh.CastBesh.Registry;
// Automatically map properties with matching names
CastMapperRegistry.Instance.RegisterAutoMap<SourceType, DestinationType>();
Diagnostics & Performance Monitoring
using Refbesh.CastBesh.Diagnostics;
MappingDiagnostics.Enabled = true;
// Perform mappings...
var dto = (UserDto)entity;
var metrics = MappingDiagnostics.GetMetrics<UserEntity, UserDto>();
Console.WriteLine($"Average: {metrics.AverageDuration.TotalMilliseconds}ms");
Console.WriteLine($"Success Rate: {metrics.SuccessRate}%");
Configuration Validation
using Refbesh.CastBesh.Configuration;
var result = ConfigurationValidator.Validate<UserEntity, UserDto>();
if (!result.IsValid)
{
Console.WriteLine("Validation Errors:");
foreach (var error in result.Errors)
Console.WriteLine($" - {error}");
}
Batch Async Processing
var entities = GetLargeList(); // 10,000+ items
// Process in batches to control memory
var dtos = await entities.CastToListAsync<UserEntity, UserDto>(
batchSize: 100,
cancellationToken: cancellationToken
);
⚡ Performance
CastBesh uses compiled expression trees for mapping, providing performance comparable to hand-written code:
- 10-50x faster than reflection-based mapping
- Zero allocation for struct keys in registry
- Aggressive inlining for hot paths
- Optimized collection processing
// Benchmark: 10,000 mappings
var sw = Stopwatch.StartNew();
for (int i = 0; i < 10000; i++)
{
var dto = (UserDto)userEntity;
}
sw.Stop();
// Typical result: ~2-5ms for 10,000 mappings
🎓 Best Practices
1. Configure Once at Startup
// In Program.cs or Startup.cs
CastBeshStartup.Configure(config =>
{
config.CreateMap<Entity1, Dto1>().WithSync(/* ... */).Build();
config.CreateMap<Entity2, Dto2>().WithSync(/* ... */).Build();
// Configure all mappings here
});
2. One Line Per Cast Direction
// Keep cast operators simple - just delegate to CastEngine
public static explicit operator UserDto(UserEntity source)
=> CastEngine.Cast<UserEntity, UserDto>(source);
3. Use Expression Body for Cast Operators
// ✅ Preferred - clean and concise
public static explicit operator UserDto(UserEntity source)
=> CastEngine.Cast<UserEntity, UserDto>(source);
// ❌ Avoid - unnecessary verbosity
public static explicit operator UserDto(UserEntity source)
{
return CastEngine.Cast<UserEntity, UserDto>(source);
}
4. Organize Mappings by Feature
// UserMappingProfile.cs
public static class UserMappingProfile
{
public static void Configure(CastConfiguration config)
{
config.CreateMap<User, UserDto>().WithSync(/* ... */).Build();
config.CreateMap<User, UserListDto>().WithSync(/* ... */).Build();
}
}
// In Startup
CastBeshStartup.Configure(config =>
{
UserMappingProfile.Configure(config);
ProductMappingProfile.Configure(config);
});
💡 When to Use CastBesh
✅ Great For:
- APIs where you frequently convert between entities and DTOs
- Clean Architecture / Onion Architecture projects
- Domain-Driven Design (DDD) applications
- Applications with many similar type conversions
- Projects where readability and maintainability matter
❌ Not Needed For:
- Very simple projects with minimal type conversions
- When types already have natural inheritance relationships
- When you only need to map 1-2 types in your entire application
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
📄 License
This project is licensed under the MIT License - see the LICENSE.txt file for details.
🔗 Links
💡 Comparison with Other Mappers
AutoMapper
// AutoMapper
var dto = _mapper.Map<UserDto>(userEntity);
// CastBesh
var dto = (UserDto)userEntity;
CastBesh Advantages:
- Native C# syntax (no dependency injection needed)
- Compile-time safety
- More explicit and readable
- Better IDE support
Mapster
// Mapster
var dto = userEntity.Adapt<UserDto>();
// CastBesh
var dto = (UserDto)userEntity;
CastBesh Advantages:
- Uses standard C# cast operators
- More intuitive for C# developers
- One-line setup per cast direction
🎉 Inspiration
Inspired by the simplicity and elegance of primitive type casting in C#:
// Primitive casting - simple and intuitive
double myDouble = 10.7;
int myInt = (int)myDouble;
// CastBesh - same simplicity for complex types!
UserEntity userEntity = GetUser();
UserDto userDto = (UserDto)userEntity;
Made with ❤️ by Refbesh
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. 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. |
-
net6.0
- No dependencies.
-
net7.0
- No dependencies.
-
net8.0
- No dependencies.
-
net9.0
- No dependencies.
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 |
|---|---|---|
| 1.0.1 | 210 | 10/2/2025 |
v1.0.1: Updated README with improved documentation