diff --git a/src/Shared/RoslynUtils/WellKnownTypes.cs b/src/Shared/RoslynUtils/WellKnownTypes.cs
index a3a5cd3061b7..deb2def60b60 100644
--- a/src/Shared/RoslynUtils/WellKnownTypes.cs
+++ b/src/Shared/RoslynUtils/WellKnownTypes.cs
@@ -19,6 +19,7 @@ public static WellKnownTypes GetOrCreate(Compilation compilation) =>
private readonly INamedTypeSymbol?[] _lazyWellKnownTypes;
private readonly Compilation _compilation;
+ private readonly INamedTypeSymbol _missingTypeSymbol;
static WellKnownTypes()
{
@@ -51,6 +52,7 @@ private WellKnownTypes(Compilation compilation)
{
_lazyWellKnownTypes = new INamedTypeSymbol?[WellKnownTypeData.WellKnownTypeNames.Length];
_compilation = compilation;
+ _missingTypeSymbol = compilation.GetTypeByMetadataName(typeof(MissingType).FullName!)!;
}
public INamedTypeSymbol Get(SpecialType type)
@@ -74,11 +76,7 @@ public INamedTypeSymbol Get(WellKnownTypeData.WellKnownType type)
private INamedTypeSymbol GetAndCache(int index)
{
- var result = GetTypeByMetadataNameInTargetAssembly(WellKnownTypeData.WellKnownTypeNames[index]);
- if (result == null)
- {
- throw new InvalidOperationException($"Failed to resolve well-known type '{WellKnownTypeData.WellKnownTypeNames[index]}'.");
- }
+ var result = GetTypeByMetadataNameInTargetAssembly(WellKnownTypeData.WellKnownTypeNames[index]) ?? _missingTypeSymbol;
Interlocked.CompareExchange(ref _lazyWellKnownTypes[index], result, null);
// GetTypeByMetadataName should always return the same instance for a name.
@@ -159,4 +157,6 @@ public static bool Implements(ITypeSymbol? type, ITypeSymbol interfaceType)
}
return false;
}
+
+ internal class MissingType { }
}
diff --git a/src/Validation/src/Microsoft.Extensions.Validation.csproj b/src/Validation/src/Microsoft.Extensions.Validation.csproj
index 72d50e224f42..35405452fdd3 100644
--- a/src/Validation/src/Microsoft.Extensions.Validation.csproj
+++ b/src/Validation/src/Microsoft.Extensions.Validation.csproj
@@ -11,6 +11,19 @@
true
+
+
+ false
+ Content
+ PreserveNewest
+
+
+
+
+
+
+
+