aweXpect.Reflection
2.0.0
Prefix Reserved
dotnet add package aweXpect.Reflection --version 2.0.0
NuGet\Install-Package aweXpect.Reflection -Version 2.0.0
<PackageReference Include="aweXpect.Reflection" Version="2.0.0" />
<PackageVersion Include="aweXpect.Reflection" Version="2.0.0" />
<PackageReference Include="aweXpect.Reflection" />
paket add aweXpect.Reflection --version 2.0.0
#r "nuget: aweXpect.Reflection, 2.0.0"
#:package aweXpect.Reflection@2.0.0
#addin nuget:?package=aweXpect.Reflection&version=2.0.0
#tool nuget:?package=aweXpect.Reflection&version=2.0.0
aweXpect.Reflection
Expectations for reflection types for aweXpect.
At a glance
Write architecture and convention tests as plain, readable assertions: select the assemblies, types
or members you care about with In or Types, then assert a rule on them with Expect.That.
// "Every async method must end in 'Async'"
await Expect.That(In.AssemblyContaining<MyClass>() // ① pick a source
.Methods() // ② navigate to a member kind
.WhichAreAsync()) // ③ filter it down
.HaveName("Async").AsSuffix(); // ④ assert
Every expectation follows the same four-part shape:
| Step | What it does | Examples |
|---|---|---|
| ① Source | choose where to look | In.AllLoadedAssemblies(), In.AssemblyContaining<T>(), In.Type<T>() |
| ② Navigate | move to a member kind | .Types(), .Methods(), .Properties(), .Fields(), .Events(), .Constructors() |
| ③ Filter (optional) | narrow the set | .WhichArePublic(), .With<T>(), .WithName(…), .Which(…) |
| ④ Assert | state the rule | Expect.That(…).HaveName(…), .AreClasses(), .Return<Task>() |
Steps ② and ③ are optional. You can assert directly on a single Type, MethodInfo, … or on a whole
Assembly, and every expectation works the same whether the subject is one item or a collection
(Assembly[], IEnumerable<Type?>, …).
The supported reflection subjects are
Assembly,
Type,
ConstructorInfo,
EventInfo,
FieldInfo,
MethodInfo and
PropertyInfo.
Real-world examples
// Verify all test classes (those containing a [Fact] or [Theory] method) follow the naming convention
await Expect.That(In.AllLoadedAssemblies()
.Public.Classes()
.WhichContainMethods(m => m.With<FactAttribute>().OrWith<TheoryAttribute>()))
.HaveName("Tests").AsSuffix();
// Verify all async methods have an "Async" suffix
await Expect.That(In.AssemblyContaining<MyClass>()
.Methods().WhichAreAsync())
.HaveName("Async").AsSuffix();
// Verify all methods with an "Async" suffix return Task or ValueTask
await Expect.That(In.AssemblyContaining<MyClass>()
.Methods().WithName("Async").AsSuffix())
.Return<Task>().OrReturn<ValueTask>();
// Verify controllers follow the naming convention
await Expect.That(In.AllLoadedAssemblies()
.Types().WhichInheritFrom<ControllerBase>())
.HaveName("Controller").AsSuffix();
// Verify each event handler is named after the event it handles (e.g. "OnOrderPlaced")
await Expect.That(In.AssemblyContaining<MyAggregate>()
.Methods().Which(m => m.GetParameters().Length == 1))
.HaveName(method => "On" + method.GetParameters()[0].ParameterType.Name);
// Verify each serializable type has exactly one parameterless constructor
await Expect.That(In.AllLoadedAssemblies()
.Types().With<SerializableAttribute>()
.WhichContainConstructors(c => c.WithoutParameters()).Exactly(1))
.AreClasses();
Filters and assertions documents the complete filter and assertion vocabulary: access modifiers, attributes, names and namespaces, type kinds, methods (return types, parameters, async, operators, …), properties, fields, events, constructors and assemblies.
Architecture rules
There is no separate rule engine: a "layer" is just a reusable type selection, and an architecture rule is
just an expectation on it. Combine several rules into a single verification with Expect.ThatAll:
Filtered.Types domainTypes = Types.InNamespace("MyApp.Domain");
Filtered.Types infrastructureTypes = Types.InNamespace("MyApp.Infrastructure");
await Expect.ThatAll(
Expect.That(domainTypes).DoNotDependOn(infrastructureTypes),
Expect.That(domainTypes).AreSealed());
A failing rule reports all violations, numbered per expectation:
Expected all of the following to succeed:
[01] Expected that domainTypes all do not depend on types within namespace "MyApp.Infrastructure" in all loaded assemblies
[02] Expected that domainTypes are all sealed
but
[01] it contained types with the dependency [
OrderService
]
[02] it contained non-sealed types [
Order,
Invoice
]
The dependency rules (DependOn / DependOnlyOn / HaveDependenciesOutside), dependency cycle detection
(HaveNoDependencyCycles) and exemptions (Except) are documented in
Architecture rules.
Documentation
The full documentation is available at docs.testably.org:
- Selecting types and members: the
InandTypessources and navigating between assemblies, types and members - Filters and assertions: the complete reference for all subject kinds, string matching options and quantifiers
- Architecture rules: type dependencies, dependency cycles and layers as type selections
- Configuration: assembly exclusions, compiler-generated members and the dependency resolver
- Comparisons: feature maps against FluentAssertions and against NetArchTest and ArchUnitNET
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. 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 was computed. 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 was computed. 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 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. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- aweXpect.Core (>= 2.32.0)
-
net10.0
- aweXpect.Core (>= 2.32.0)
-
net8.0
- aweXpect.Core (>= 2.32.0)
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 |
|---|---|---|
| 2.0.0 | 95 | 6/7/2026 |
| 2.0.0-pre.2 | 53 | 6/6/2026 |
| 2.0.0-pre.1 | 52 | 6/4/2026 |
| 1.6.0 | 100 | 6/3/2026 |
| 1.5.0 | 104 | 5/31/2026 |
| 1.4.0 | 98 | 5/30/2026 |
| 1.3.0 | 96 | 5/28/2026 |
| 1.2.0 | 98 | 5/27/2026 |
| 1.1.0 | 101 | 5/10/2026 |
| 1.0.0 | 285 | 9/19/2025 |
| 0.7.0 | 203 | 9/11/2025 |
| 0.6.0 | 208 | 8/17/2025 |
| 0.5.0 | 177 | 8/16/2025 |
| 0.4.0 | 141 | 8/15/2025 |
| 0.3.0 | 191 | 7/27/2025 |
| 0.2.0 | 199 | 4/19/2025 |
| 0.1.0 | 191 | 4/18/2025 |