Aspekt is a lightweight, powerful Aspect-Oriented Programming (AOP) foundation library for .NET that allows you to implement cross-cutting concerns using attributes. It supports modern .NET versions including .NET 6.0, 8.0, and 9.0, with async/await patterns and comprehensive Design by Contract capabilities.
- Attribute-Based AOP: Apply aspects declaratively using C# attributes
- Async Support: Full support for async/await patterns with
ValueTaskmethods - Design by Contract: Comprehensive contract system with preconditions, postconditions, and invariants
- Return Value Interception: Modify return values using
IAspectExitHandler<T> - Modern .NET Support: Compatible with .NET 6.0, 8.0, 9.0, and .NET Standard 2.1
- Post-Compilation Weaving: IL manipulation using Mono.Cecil for zero-overhead aspect application
- Built-in Logging: Ready-to-use logging aspects with customizable formatters
- Thread-Safe: Designed for multi-threaded applications
# Core AOP functionality
Install-Package Aspekt -Version 3.0.0
# Design by Contract support
Install-Package Aspekt.Contracts -Version 3.0.0
# Logging aspects
Install-Package Aspekt.Logging -Version 3.0.0using Aspekt;
public class LoggingAspect : Aspect
{
public override void OnEntry(MethodArguments args)
{
Console.WriteLine($"Entering: {args.FullName}");
}
public override void OnExit(MethodArguments args)
{
Console.WriteLine($"Exiting: {args.FullName}");
}
public override void OnException(MethodArguments args, Exception ex)
{
Console.WriteLine($"Exception in {args.FullName}: {ex.Message}");
}
}public class Calculator
{
[Logging]
public int Add(int x, int y)
{
return x + y;
}
[Logging]
public async Task<string> GetDataAsync()
{
await Task.Delay(100);
return "Hello, World!";
}
}public class ResultModifierAspect : Aspect, IAspectExitHandler<string>
{
public string OnExit(MethodArguments args, string result)
{
return $"Modified: {result}";
}
}
public class Service
{
[ResultModifier]
public string GetMessage() => "Original";
// Returns: "Modified: Original"
}using Aspekt.Contracts;
public class BankAccount
{
private decimal _balance;
[Invariant(nameof(_balance), Contract.Comparison.GreaterThanEqualTo, 0)]
public decimal Balance => _balance;
[Require(nameof(amount), Contract.Comparison.GreaterThan, 0)]
[Ensure(Contract.Comparison.GreaterThanEqualTo, 0)]
public decimal Deposit(decimal amount)
{
_balance += amount;
return _balance;
}
}- Getting Started Guide - Complete guide from installation to advanced features
- Contracts Documentation - Design by Contract with preconditions, postconditions, and invariants
- API Reference - Detailed API documentation for all components
- Examples - Real-world usage examples and patterns
- Troubleshooting Guide - Common issues and solutions
Aspekt uses post-compilation IL weaving via Mono.Cecil. When you apply an aspect attribute to a method:
- Build Time: Your code compiles normally
- Post-Build: Aspekt.Bootstrap.Host processes your assembly
- IL Weaving: Aspect calls are injected into your methods
- Runtime: Aspects execute seamlessly with your code
// Your code:
[LoggingAspect]
public void DoWork() { /* your logic */ }
// Becomes (conceptually):
public void DoWork()
{
var aspect = new LoggingAspect();
var args = new MethodArguments(/* method info */);
aspect.OnEntry(args);
try
{
/* your original logic */
aspect.OnExit(args);
}
catch (Exception ex)
{
aspect.OnException(args, ex);
throw;
}
}- Aspekt: Core AOP functionality and base
Aspectclass - Aspekt.Contracts: Design by Contract implementation
- Aspekt.Logging: Built-in logging aspects with multiple formatters
- Aspekt.Bootstrap: IL weaving engine using Mono.Cecil
- Aspekt.Test: Comprehensive test suite with 100+ tests
- .NET SDK 6.0 or later
- Visual Studio 2022 or VS Code
- MSBuild 17.0+
# Clone and build
git clone https://github.com/mvpete/aspekt.git
cd aspekt
dotnet build
dotnet testThis project uses GitHub Actions for continuous integration and deployment:
- Automated Testing: Multi-version testing across .NET 6.0, 8.0, and 9.0
- Code Quality: Automated formatting, analysis, and security scanning
- Package Publishing: Automatic NuGet releases on tagged versions
- Documentation: Link validation and spell checking
See Pipeline Documentation for detailed information about the build and release process.
Aspekt is designed for minimal runtime overhead:
- Zero reflection at runtime
- Compile-time weaving means no performance impact from AOP infrastructure
- Selective application - only methods with aspects are modified
- Async-aware - proper support for async/await patterns
We welcome contributions! Please see CONTRIBUTING.md for guidelines.
- Fork the repository
- Create a feature branch
- Add tests for your changes
- Ensure all tests pass
- Submit a pull request
This project is licensed under the MIT License - see the LICENSE file for details.
- Built with Mono.Cecil for IL manipulation
- Inspired by PostSharp and other AOP frameworks
- Thanks to all contributors and users
Get started today: Check out the Getting Started Guide to begin using Aspekt in your projects!