Muslim.Extensions
10.0.1
dotnet add package Muslim.Extensions --version 10.0.1
NuGet\Install-Package Muslim.Extensions -Version 10.0.1
<PackageReference Include="Muslim.Extensions" Version="10.0.1" />
<PackageVersion Include="Muslim.Extensions" Version="10.0.1" />
<PackageReference Include="Muslim.Extensions" />
paket add Muslim.Extensions --version 10.0.1
#r "nuget: Muslim.Extensions, 10.0.1"
#:package Muslim.Extensions@10.0.1
#addin nuget:?package=Muslim.Extensions&version=10.0.1
#tool nuget:?package=Muslim.Extensions&version=10.0.1
Muslim.Extensions
Small extension methods for .NET 10: object mapping, password hashing, empty checks, enum parsing and date conversion.
dotnet add package Muslim.Extensions
All methods live in the Muslim.Extensions namespace.
| Method | What it does |
|---|---|
obj.Map<TDto>() |
Maps an object with AutoMapper |
password.HashPassword() |
Hashes a password (PBKDF2-SHA256, salted) |
password.VerifyHashedPassword(hash) |
Checks a password against a stored hash |
hash.NeedsPasswordRehash() |
Tells you a stored hash should be upgraded |
text.ComputeSha256Hash() |
SHA-256 of a string, as lowercase hex |
value.IsEmpty() |
true for null or the type's default value |
obj.IsObjEmpty() |
true when no property of an object or collection has a value |
text.ToEnum<T>() |
Parses a string into an enum |
date.ToDateOnly() |
DateTime or DateTime? to DateOnly |
number.NotNull(), text.NotNull() |
int? to 0, string? to "" |
number.IsNull() |
true when an int? has no value |
Mapping
Map<TDto>() uses the IMapper registered in your container, through
Muslim.Inject. Set it up once in Program.cs:
using Muslim.Inject;
builder.Services.AddAutoMapper(typeof(ProductProfile).Assembly);
var app = builder.Build();
InjectExtensions.SetServiceProvider(app.Services);
public class ProductProfile : Profile
{
public ProductProfile() => CreateMap<Product, ProductDto>();
}
Then map anywhere, without injecting IMapper:
ProductDto dto = product.Map<ProductDto>();
List<ProductDto> list = products.Map<List<ProductDto>>();
If SetServiceProvider was not called, or IMapper is not registered, Map throws an
InvalidOperationException that says which one is missing.
Password hashing
// sign-up
user.PasswordHash = request.Password.HashPassword();
// sign-in
if (!request.Password.VerifyHashedPassword(user.PasswordHash))
return Results.Unauthorized();
if (user.PasswordHash.NeedsPasswordRehash())
{
user.PasswordHash = request.Password.HashPassword();
await db.SaveChangesAsync();
}
- The hash looks like
PBKDF2-SHA256$600000$salt$key. Store it in a string column of at least 100 characters. VerifyHashedPasswordalso accepts old hashes made withComputeSha256Hash.NeedsPasswordRehashreturnstruefor those, so users move to the stronger hash the next time they sign in.- Hashes are compared in constant time. An empty or broken stored hash returns
falseinstead of throwing. - Do not use
ComputeSha256Hashfor new passwords. It is a plain digest with no salt.
Empty checks
0.IsEmpty(); // true
"".IsEmpty(); // false — use string.IsNullOrEmpty for strings
((int?)null).IsEmpty(); // true
Guid.Empty.IsEmpty(); // true
new ProductFilterDto().IsObjEmpty(); // true — nothing filled in
new ProductFilterDto { Name = "a" }.IsObjEmpty(); // false
new List<string>().IsObjEmpty(); // true
IsObjEmpty is useful for "did the client send anything?" checks on a DTO.
Other helpers
var status = "Active".ToEnum<OrderStatus>(); // throws ArgumentException for an unknown value
DateOnly day = order.CreatedDate.ToDateOnly(); // works for DateTime and DateTime?
int count = maybeCount.NotNull(); // null -> 0
string name = maybeName.NotNull(); // null -> ""
Good to know
- Only
Map<TDto>()needs setup. Every other method works on its own. - This package uses AutoMapper 12.0.1, which NuGet flags with a security advisory (GHSA-rvv3-g6hj-g44x). Moving to a newer AutoMapper changes its API and license, so it has not been done yet. Check whether the advisory affects your inputs.
Related packages
| Package | Use it for |
|---|---|
| Muslim.Inject | Automatic dependency registration |
Coding-agent guidance
When you build a project that uses this package, a short guide for AI coding agents is copied to
.agents/skills/muslim-extensions/ at the root of your repository. Agents that read skills from
.agents/skills, such as Codex and GitHub Copilot in VS Code, use it to write correct code against
this package. Your own files and other skills are never touched, and nothing is deleted
automatically.
To turn it off, add this to your project or Directory.Build.props:
<PropertyGroup>
<MuslimExtensionsGenerateSkill>false</MuslimExtensionsGenerateSkill>
</PropertyGroup>
License
See LICENSE.txt.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. 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. |
-
net10.0
- AutoMapper.Extensions.Microsoft.DependencyInjection (>= 12.0.1)
- Muslim.Inject (>= 10.0.1)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Muslim.Extensions:
| Package | Downloads |
|---|---|
|
Muslim.GenericRepository
EF Core repository for entities with audit columns: reads, writes, soft delete, bulk operations and raw SQL, with CreatedBy/UpdateBy/DeletedBy and UTC timestamps written automatically. Implements Muslim.GenericRepository.Interface. |
GitHub repositories
This package is not used by any popular GitHub repositories.
Adds HashPassword/VerifyHashedPassword/NeedsPasswordRehash (PBKDF2). Fixes Map<T>() static-initializer failures, IsObjEmpty crashes on strings/null items and value-type properties, and boxed IsEmpty. Generates .agents/skills/muslim-extensions on consumer builds (disable with MuslimExtensionsGenerateSkill=false). See CHANGELOG.md.