A comprehensive collection of extension methods and utilities for .NET applications that provide foundational functionality for the entire DKNet framework.
DKNet.Fw.Extensions is the foundational library of the DKNet framework that provides a rich set of extension methods and utilities for common .NET types. This library enhances the built-in .NET functionality with practical extensions for strings, types, enums, async operations, and more. It serves as the bedrock for all other DKNet components by providing consistent utilities and helper methods.
In the Onion Architecture, DKNet.Fw.Extensions provides the Cross-Cutting Concerns layer that supports all other layers without creating dependencies:
┌─────────────────────────────────────────────────────────────────┐
│ 🌐 Presentation Layer │
│ │
│ Uses: String validation, Type checking, Enum info │
└─────────────────────────┬───────────────────────────────────────┘
│
┌─────────────────────────┴───────────────────────────────────────┐
│ 🎯 Application Layer │
│ │
│ Uses: Service registration, Async processing, Encryption │
└─────────────────────────┬───────────────────────────────────────┘
│
┌─────────────────────────┴───────────────────────────────────────┐
│ 💼 Domain Layer │
│ │
│ Uses: Type extensions, Enum utilities, Property helpers │
└─────────────────────────┬───────────────────────────────────────┘
│
┌─────────────────────────┴───────────────────────────────────────┐
│ 🗄️ Infrastructure Layer │
│ │
│ Uses: All extensions for data processing & external APIs │
└─────────────────────────┬───────────────────────────────────────┘
│
┌─────────────────────────┴───────────────────────────────────────┐
│ ⚙️ DKNet.Fw.Extensions (Foundation) │
│ │
│ • No dependencies on other layers │
│ • Provides utilities for all layers │
│ • Enables clean, readable code │
└─────────────────────────────────────────────────────────────────┘
dotnet add package DKNet.Fw.Extensions
using DKNet.Fw.Extensions;
// String validation
var phoneNumber = "123-456-7890";
bool isNumeric = phoneNumber.IsNumber(); // false (contains dashes)
var price = "99.99";
bool isPriceValid = price.IsNumber(); // true
// Extract digits from formatted strings
var cleanNumber = phoneNumber.ExtractDigits(); // "1234567890"
using System.ComponentModel.DataAnnotations;
using DKNet.Fw.Extensions;
public enum OrderStatus
{
[Display(Name = "Pending", Description = "Order is waiting for processing")]
Pending,
[Display(Name = "Processing", Description = "Order is being processed")]
Processing,
[Display(Name = "Completed", Description = "Order has been completed")]
Completed
}
// Usage
OrderStatus status = OrderStatus.Pending;
var enumInfo = status.GetEumInfo();
Console.WriteLine($"Status: {enumInfo.Name}"); // "Status: Pending"
Console.WriteLine($"Description: {enumInfo.Description}"); // "Description: Order is waiting for processing"
// Get all enum information
var allStatuses = EnumExtensions.GetEumInfos<OrderStatus>();
foreach (var info in allStatuses)
{
Console.WriteLine($"{info.Key}: {info.Name} - {info.Description}");
}
using DKNet.Fw.Extensions;
// Check if a type implements an interface
public interface IEntity
{
int Id { get; set; }
}
public class User : IEntity
{
public int Id { get; set; }
public string Name { get; set; }
}
// Type checking
Type userType = typeof(User);
bool implementsEntity = userType.IsImplementOf(typeof(IEntity)); // true
// Useful for repository pattern implementations
public class GenericRepository<T> where T : class
{
public void ValidateEntityType()
{
if (!typeof(T).IsImplementOf(typeof(IEntity)))
{
throw new ArgumentException("T must implement IEntity");
}
}
}
using Microsoft.Extensions.DependencyInjection;
using DKNet.Fw.Extensions;
public void ConfigureServices(IServiceCollection services)
{
// Register multiple implementations with a key
var handlerTypes = new[]
{
typeof(OrderCreatedHandler),
typeof(OrderUpdatedHandler),
typeof(OrderDeletedHandler)
};
services.AsKeyedImplementedInterfaces("OrderHandlers", handlerTypes, ServiceLifetime.Scoped);
// Later resolve by key
var provider = services.BuildServiceProvider();
var handlers = provider.GetKeyedServices<IEventHandler>("OrderHandlers");
}
using DKNet.Fw.Extensions;
using System.Reflection;
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
// Dynamic property manipulation
var product = new Product { Id = 1, Name = "Laptop", Price = 999.99m };
var properties = typeof(Product).GetProperties();
foreach (var property in properties)
{
if (property.Name.IsNumber()) // Using string extension
{
// Handle numeric properties differently
var value = property.GetValue(product);
Console.WriteLine($"{property.Name}: {value}");
}
}
using DKNet.Fw.Extensions;
// Note: Actual encryption classes would need to be examined for exact usage
// This is a conceptual example based on the encryption folder structure
public class UserService
{
private readonly IStringEncryption _encryption;
public UserService(IStringEncryption encryption)
{
_encryption = encryption;
}
public async Task<User> CreateUserAsync(string email, string password)
{
// Encrypt sensitive data before storing
var encryptedEmail = await _encryption.EncryptAsync(email);
var hashedPassword = await _encryption.HashAsync(password);
return new User
{
Email = encryptedEmail,
PasswordHash = hashedPassword
};
}
}
using DKNet.Fw.Extensions;
public class Email
{
private readonly string _value;
public Email(string value)
{
if (string.IsNullOrWhiteSpace(value))
throw new ArgumentException("Email cannot be empty");
// Use string extensions for validation
if (!IsValidEmail(value))
throw new ArgumentException("Invalid email format");
_value = value;
}
private static bool IsValidEmail(string email)
{
// Custom validation using string extensions
return email.Contains("@") && !email.IsNumber();
}
public static implicit operator string(Email email) => email._value;
public override string ToString() => _value;
}
using DKNet.Fw.Extensions;
public interface IEntity
{
int Id { get; set; }
}
public class Repository<T> where T : class, IEntity
{
public Repository()
{
// Validate that T implements IEntity using type extensions
if (!typeof(T).IsImplementOf(typeof(IEntity)))
{
throw new InvalidOperationException($"Type {typeof(T).Name} must implement IEntity");
}
}
public async Task<T> GetByIdAsync(int id)
{
// Implementation using the validated type
// ...
}
}
using DKNet.Fw.Extensions;
using System.Reflection;
public class EventDispatcher
{
public void RegisterEventHandlers(Assembly assembly)
{
var handlerTypes = assembly.GetTypes()
.Where(t => t.IsImplementOf(typeof(IEventHandler)))
.ToList();
// Register handlers using service collection extensions
// services.AsKeyedImplementedInterfaces("EventHandlers", handlerTypes);
}
}
DKNet.Fw.Extensions integrates seamlessly with other DKNet components:
💡 Pro Tip: Use the enum extensions with Display attributes to maintain a consistent ubiquitous language throughout your domain model. This helps bridge the gap between technical implementation and business terminology.