diff --git a/eng/TestLibrary.props b/eng/TestLibrary.props
index d939173fa4d..7acc01fdf0a 100644
--- a/eng/TestLibrary.props
+++ b/eng/TestLibrary.props
@@ -1,6 +1,23 @@
+
+
+
+ <_TUnitGeneratedNamespaceCompile Include="@(Compile)" Condition="'%(Filename)%(Extension)' == 'TUnit.Core.GeneratedNamespace.cs'" />
+ <_TUnitOtherCompile Include="@(Compile)" Exclude="@(_TUnitGeneratedNamespaceCompile)" Condition="'@(_TUnitGeneratedNamespaceCompile)' != ''" />
+
+
+
+
+
Library
diff --git a/src/TUnit.Core/TUnit.Core.GeneratedNamespace.cs b/src/TUnit.Core/TUnit.Core.GeneratedNamespace.cs
new file mode 100644
index 00000000000..2ac19f46719
--- /dev/null
+++ b/src/TUnit.Core/TUnit.Core.GeneratedNamespace.cs
@@ -0,0 +1,13 @@
+//
+// Added to test projects by TUnit.Core.props so it compiles ahead of the project's own files.
+//
+// The C# compiler writes namespaces to the assembly in reverse order of their first declaration.
+// Source-generated trees are always added after the project's files, so without this declaration
+// the TUnit.Generated types (large static constructors registering every test) are written at the
+// very start of the assembly. Antivirus scanners such as Microsoft Defender analyse code at the
+// start of an assembly far more expensively, which added seconds to every build and first test run
+// of large test projects on Windows. Declaring the namespace first moves the generated types to the
+// end of the assembly instead.
+namespace TUnit.Generated
+{
+}
diff --git a/src/TUnit.Core/TUnit.Core.csproj b/src/TUnit.Core/TUnit.Core.csproj
index 0ffb72e7670..9f759056ad6 100644
--- a/src/TUnit.Core/TUnit.Core.csproj
+++ b/src/TUnit.Core/TUnit.Core.csproj
@@ -35,6 +35,18 @@
true
$(BuildPath)
+
+
+
+
+ true
+ $(BuildTransitivePath)
+
+
+
+ true
+ $(BuildPath)
+
+
+
+
+
+
diff --git a/tools/tunit-nuget-tester/TUnit.NugetTester/TUnit.NugetTester/GeneratedTypeOrderTests.cs b/tools/tunit-nuget-tester/TUnit.NugetTester/TUnit.NugetTester/GeneratedTypeOrderTests.cs
new file mode 100644
index 00000000000..b4beefe47f5
--- /dev/null
+++ b/tools/tunit-nuget-tester/TUnit.NugetTester/TUnit.NugetTester/GeneratedTypeOrderTests.cs
@@ -0,0 +1,32 @@
+using System.Diagnostics.CodeAnalysis;
+using System.Reflection;
+
+namespace TUnit.NugetTester;
+
+///
+/// TUnit.Core.props adds TUnit.Core.GeneratedNamespace.cs ahead of the project's own files so the compiler
+/// emits the source-generated TUnit.Generated types after the user's types. Emitting them first made
+/// Microsoft Defender scan large test assemblies for seconds on every build (see PR #6908).
+/// This project consumes the packed packages, so it guards the real NuGet import path.
+///
+public class GeneratedTypeOrderTests
+{
+ [Test]
+ [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Only inspects this assembly's own type definitions.")]
+ public async Task Generated_Types_Are_Emitted_After_User_Types()
+ {
+ var types = typeof(GeneratedTypeOrderTests).Assembly.GetTypes();
+
+ var generatedTypes = types.Where(t => t.Namespace == "TUnit.Generated").ToArray();
+ var userTypes = types.Where(t => !t.IsNested && t.Namespace == typeof(GeneratedTypeOrderTests).Namespace).ToArray();
+
+ await Assert.That(generatedTypes).IsNotEmpty();
+ await Assert.That(userTypes).IsNotEmpty();
+
+ // TypeDef metadata tokens follow the order the compiler emitted the types in.
+ var firstGenerated = generatedTypes.Min(t => t.MetadataToken);
+ var lastUser = userTypes.Max(t => t.MetadataToken);
+
+ await Assert.That(firstGenerated).IsGreaterThan(lastUser);
+ }
+}