From e57fd525386f9281ed705ad85d0a1ca87699e995 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Apr 2026 20:42:55 +0000 Subject: [PATCH 1/9] Add NullScope compatibility type to Microsoft.Extensions.Logging.Abstractions.Internal namespace Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/5c5fb4d4-ec9e-4d85-a918-813e8b551daf Co-authored-by: ericstj <8918108+ericstj@users.noreply.github.com> --- ...crosoft.Extensions.Logging.Abstractions.cs | 11 +++++++ .../src/NullScope.cs | 30 +++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 src/libraries/Microsoft.Extensions.Logging.Abstractions/src/NullScope.cs diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.cs index 34f8935ac470cd..b9a61d6f120e44 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.cs @@ -226,3 +226,14 @@ public interface IBufferedLogger void LogRecords(System.Collections.Generic.IEnumerable records); } } +namespace Microsoft.Extensions.Logging.Abstractions.Internal +{ + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + [System.ObsoleteAttribute("This type is retained only for compatibility. The recommended alternative is ConsoleLoggerOptions.", error: true)] + public partial class NullScope : System.IDisposable + { + private NullScope() { } + public static Microsoft.Extensions.Logging.Abstractions.Internal.NullScope Instance { get { throw null; } } + public void Dispose() { } + } +} diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/NullScope.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/NullScope.cs new file mode 100644 index 00000000000000..a0fbd563505432 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/NullScope.cs @@ -0,0 +1,30 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.ComponentModel; + +namespace Microsoft.Extensions.Logging.Abstractions.Internal +{ + /// + /// An empty scope without any logic. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + [Obsolete("This type is retained only for compatibility. The recommended alternative is ConsoleLoggerOptions.", error: true)] + public class NullScope : IDisposable + { + /// + /// Returns the shared instance of . + /// + public static NullScope Instance { get; } = new NullScope(); + + private NullScope() + { + } + + /// + public void Dispose() + { + } + } +} From 0b9a8d7da8b3ec06399a527cda99ecb8b40ce5b4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Apr 2026 21:25:46 +0000 Subject: [PATCH 2/9] Add compatibility shims with public counterparts in both namespaces for TypeNameHelper, FormattedLogValues, LogValuesFormatter, and NullScope Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/85535733-d8cc-4425-a106-63e3ccf52b70 Co-authored-by: ericstj <8918108+ericstj@users.noreply.github.com> --- ...crosoft.Extensions.Logging.Abstractions.cs | 67 ++++++++++++++++++- ...oft.Extensions.Logging.Abstractions.csproj | 1 + .../src/FormattedLogValues.cs | 11 ++- .../src/FormattedLogValuesObsolete.cs | 46 +++++++++++++ .../src/LogValuesFormatter.cs | 19 +++++- .../src/LogValuesFormatterObsolete.cs | 43 ++++++++++++ .../src/NullScope.cs | 2 +- .../src/NullScopeLogging.cs | 27 ++++++++ .../src/TypeNameHelper.cs | 36 ++++++++++ .../src/TypeNameHelperObsolete.cs | 26 +++++++ .../Microsoft.Extensions.Logging.Forwards.cs | 4 ++ .../src/Properties/TypeForwards.cs | 4 ++ 12 files changed, 282 insertions(+), 4 deletions(-) create mode 100644 src/libraries/Microsoft.Extensions.Logging.Abstractions/src/FormattedLogValuesObsolete.cs create mode 100644 src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LogValuesFormatterObsolete.cs create mode 100644 src/libraries/Microsoft.Extensions.Logging.Abstractions/src/NullScopeLogging.cs create mode 100644 src/libraries/Microsoft.Extensions.Logging.Abstractions/src/TypeNameHelper.cs create mode 100644 src/libraries/Microsoft.Extensions.Logging.Abstractions/src/TypeNameHelperObsolete.cs diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.cs index b9a61d6f120e44..bbbef51491c7fa 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.cs @@ -161,6 +161,26 @@ public partial class ProviderAliasAttribute : System.Attribute public ProviderAliasAttribute(string alias) { } public string Alias { get { throw null; } } } + public partial struct FormattedLogValues : System.Collections.Generic.IReadOnlyList>, System.Collections.Generic.IEnumerable>, System.Collections.IEnumerable, System.Collections.Generic.IReadOnlyCollection> + { + private readonly object _dummy; + private readonly int _dummyPrimitive; + public FormattedLogValues(string? format, params object?[]? values) { } + public System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } + public int Count { get { throw null; } } + public System.Collections.Generic.IEnumerator> GetEnumerator() { throw null; } + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } + public override string ToString() { throw null; } + } + public sealed partial class LogValuesFormatter + { + public LogValuesFormatter(string format) { } + public string OriginalFormat { get { throw null; } } + public System.Collections.Generic.List ValueNames { get { throw null; } } + public string Format(object?[]? values) { throw null; } + public System.Collections.Generic.KeyValuePair GetValue(object?[] values, int index) { throw null; } + public System.Collections.Generic.IEnumerable> GetValues(object[] values) { throw null; } + } } namespace Microsoft.Extensions.Logging.Abstractions { @@ -225,15 +245,60 @@ public interface IBufferedLogger { void LogRecords(System.Collections.Generic.IEnumerable records); } + public sealed partial class NullScope : System.IDisposable + { + private NullScope() { } + public static Microsoft.Extensions.Logging.Abstractions.NullScope Instance { get { throw null; } } + public void Dispose() { } + } + public static partial class TypeNameHelper + { + [return: System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute("item")] + public static string? GetTypeDisplayName(object? item, bool fullName = true) { throw null; } + public static string GetTypeDisplayName(System.Type type, bool fullName = true, bool includeGenericParameterNames = false, bool includeGenericParameters = true, char nestedTypeDelimiter = '+') { throw null; } + } } namespace Microsoft.Extensions.Logging.Abstractions.Internal { [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - [System.ObsoleteAttribute("This type is retained only for compatibility. The recommended alternative is ConsoleLoggerOptions.", error: true)] + [System.ObsoleteAttribute("This type is retained only for compatibility. The recommended alternative is NullScope in the Microsoft.Extensions.Logging.Abstractions namespace.", error: true)] public partial class NullScope : System.IDisposable { private NullScope() { } public static Microsoft.Extensions.Logging.Abstractions.Internal.NullScope Instance { get { throw null; } } public void Dispose() { } } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + [System.ObsoleteAttribute("This type is retained only for compatibility. Do not use.", error: true)] + public static partial class TypeNameHelper + { + [return: System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute("item")] + public static string? GetTypeDisplayName(object? item, bool fullName = true) { throw null; } + public static string GetTypeDisplayName(System.Type type, bool fullName = true, bool includeGenericParameterNames = false, bool includeGenericParameters = true, char nestedTypeDelimiter = '+') { throw null; } + } +} +namespace Microsoft.Extensions.Logging.Internal +{ + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + [System.ObsoleteAttribute("This type is retained only for compatibility. The recommended alternative is Microsoft.Extensions.Diagnostics.Testing.", error: true)] + public sealed partial class FormattedLogValues : System.Collections.Generic.IReadOnlyList>, System.Collections.Generic.IEnumerable>, System.Collections.IEnumerable, System.Collections.Generic.IReadOnlyCollection> + { + public FormattedLogValues(string? format, params object?[]? values) { } + public System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } + public int Count { get { throw null; } } + public System.Collections.Generic.IEnumerator> GetEnumerator() { throw null; } + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } + public override string ToString() { throw null; } + } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + [System.ObsoleteAttribute("This type is retained only for compatibility. The recommended alternative is Microsoft.Extensions.Diagnostics.Testing.", error: true)] + public sealed partial class LogValuesFormatter + { + public LogValuesFormatter(string format) { } + public string OriginalFormat { get { throw null; } } + public System.Collections.Generic.List ValueNames { get { throw null; } } + public string Format(object?[]? values) { throw null; } + public System.Collections.Generic.KeyValuePair GetValue(object?[] values, int index) { throw null; } + public System.Collections.Generic.IEnumerable> GetValues(object[] values) { throw null; } + } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.csproj b/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.csproj index 19f520bbca8999..68eb86172fedb3 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.csproj @@ -14,6 +14,7 @@ + diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/FormattedLogValues.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/FormattedLogValues.cs index dd9d053a675710..f8214da89acf25 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/FormattedLogValues.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/FormattedLogValues.cs @@ -14,7 +14,7 @@ namespace Microsoft.Extensions.Logging /// LogValues to enable formatting options supported by . /// This also enables using {NamedFormatItem} in the format string. /// - internal struct FormattedLogValues : IReadOnlyList> + public struct FormattedLogValues : IReadOnlyList> { internal const int MaxCachedFormatters = 1024; private const string NullFormat = "[null]"; @@ -30,6 +30,11 @@ internal struct FormattedLogValues : IReadOnlyList // for testing purposes internal LogValuesFormatter? Formatter => _formatter; + /// + /// Initializes a new instance of the struct. + /// + /// The named format string. + /// The values to substitute into the format string. public FormattedLogValues(string? format, params object?[]? values) { if (values != null && values.Length != 0 && format != null) @@ -60,6 +65,7 @@ public FormattedLogValues(string? format, params object?[]? values) _cachedToString = null; } + /// public KeyValuePair this[int index] { get @@ -78,6 +84,7 @@ public FormattedLogValues(string? format, params object?[]? values) } } + /// public int Count { get @@ -91,6 +98,7 @@ public int Count } } + /// public IEnumerator> GetEnumerator() { for (int i = 0; i < Count; ++i) @@ -99,6 +107,7 @@ public int Count } } + /// public override string ToString() { if (_formatter == null) diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/FormattedLogValuesObsolete.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/FormattedLogValuesObsolete.cs new file mode 100644 index 00000000000000..4a60475e4d65a3 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/FormattedLogValuesObsolete.cs @@ -0,0 +1,46 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; + +namespace Microsoft.Extensions.Logging.Internal +{ + /// + /// LogValues to enable formatting options supported by . + /// This also enables using {NamedFormatItem} in the format string. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + [Obsolete("This type is retained only for compatibility. The recommended alternative is Microsoft.Extensions.Diagnostics.Testing.", error: true)] + public sealed class FormattedLogValues : IReadOnlyList> + { + private readonly Microsoft.Extensions.Logging.FormattedLogValues _inner; + + /// + /// Initializes a new instance of the class. + /// + /// The format string. + /// The values. + public FormattedLogValues(string? format, params object?[]? values) + { + _inner = new Microsoft.Extensions.Logging.FormattedLogValues(format, values); + } + + /// + public KeyValuePair this[int index] => _inner[index]; + + /// + public int Count => _inner.Count; + + /// + public IEnumerator> GetEnumerator() => _inner.GetEnumerator(); + + /// + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + public override string ToString() => _inner.ToString(); + } +} diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LogValuesFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LogValuesFormatter.cs index 2fdba83aa3206c..4437302b31f67a 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LogValuesFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LogValuesFormatter.cs @@ -13,7 +13,7 @@ namespace Microsoft.Extensions.Logging /// /// Formatter to convert the named format items like {NamedformatItem} to format. /// - internal sealed class LogValuesFormatter + public sealed class LogValuesFormatter { private const string NullValue = "(null)"; private readonly List _valueNames = new List(); @@ -27,6 +27,10 @@ internal sealed class LogValuesFormatter // - Be annotated as [SkipLocalsInit] to avoid zero'ing the stackalloc'd char span // - Format _valueNames.Count directly into a span + /// + /// Initializes a new instance of the class. + /// + /// The named format string. public LogValuesFormatter(string format) { ArgumentNullException.ThrowIfNull(format); @@ -82,7 +86,10 @@ public LogValuesFormatter(string format) #endif } + /// Gets the original format string. public string OriginalFormat { get; } + + /// Gets the list of named format parameter names. public List ValueNames => _valueNames; private static int FindBraceIndex(string format, char brace, int startIndex, int endIndex) @@ -133,6 +140,9 @@ private static int FindBraceIndex(string format, char brace, int startIndex, int return braceIndex; } + /// Formats the given values using the format string. + /// The values to format. + /// The formatted string. public string Format(object?[]? values) { object?[]? formattedValues = values; @@ -218,6 +228,10 @@ internal string Format(object? arg0, object? arg1, object? arg2) => string.Format(CultureInfo.InvariantCulture, _format, FormatArgument(arg0), FormatArgument(arg1), FormatArgument(arg2)); #endif + /// Gets the key/value pair for the format item at the specified index. + /// The values array. + /// The index of the value to retrieve. + /// A key/value pair for the format item. public KeyValuePair GetValue(object?[] values, int index) { if (index < 0 || index > _valueNames.Count) @@ -233,6 +247,9 @@ internal string Format(object? arg0, object? arg1, object? arg2) => return new KeyValuePair("{OriginalFormat}", OriginalFormat); } + /// Gets an enumerable of key/value pairs for all format items. + /// The values array. + /// An enumerable of key/value pairs. public IEnumerable> GetValues(object[] values) { var valueArray = new KeyValuePair[values.Length + 1]; diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LogValuesFormatterObsolete.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LogValuesFormatterObsolete.cs new file mode 100644 index 00000000000000..3bddcdb7dc432e --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LogValuesFormatterObsolete.cs @@ -0,0 +1,43 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.ComponentModel; + +namespace Microsoft.Extensions.Logging.Internal +{ + /// + /// Formatter to convert the named format items like {NamedformatItem} to format. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + [Obsolete("This type is retained only for compatibility. The recommended alternative is Microsoft.Extensions.Diagnostics.Testing.", error: true)] + public sealed class LogValuesFormatter + { + private readonly Microsoft.Extensions.Logging.LogValuesFormatter _inner; + + /// + /// Initializes a new instance of the class. + /// + /// The named format string. + public LogValuesFormatter(string format) + { + _inner = new Microsoft.Extensions.Logging.LogValuesFormatter(format); + } + + /// + public string OriginalFormat => _inner.OriginalFormat; + + /// + public List ValueNames => _inner.ValueNames; + + /// + public string Format(object?[]? values) => _inner.Format(values); + + /// + public KeyValuePair GetValue(object?[] values, int index) => _inner.GetValue(values, index); + + /// + public IEnumerable> GetValues(object[] values) => _inner.GetValues(values); + } +} diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/NullScope.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/NullScope.cs index a0fbd563505432..461a1551d73df8 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/NullScope.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/NullScope.cs @@ -10,7 +10,7 @@ namespace Microsoft.Extensions.Logging.Abstractions.Internal /// An empty scope without any logic. /// [EditorBrowsable(EditorBrowsableState.Never)] - [Obsolete("This type is retained only for compatibility. The recommended alternative is ConsoleLoggerOptions.", error: true)] + [Obsolete("This type is retained only for compatibility. The recommended alternative is NullScope in the Microsoft.Extensions.Logging.Abstractions namespace.", error: true)] public class NullScope : IDisposable { /// diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/NullScopeLogging.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/NullScopeLogging.cs new file mode 100644 index 00000000000000..88e47416c134bf --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/NullScopeLogging.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +namespace Microsoft.Extensions.Logging.Abstractions +{ + /// + /// An empty scope without any logic. + /// + public sealed class NullScope : IDisposable + { + /// + /// Returns the shared instance of . + /// + public static NullScope Instance { get; } = new NullScope(); + + private NullScope() + { + } + + /// + public void Dispose() + { + } + } +} diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/TypeNameHelper.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/TypeNameHelper.cs new file mode 100644 index 00000000000000..830b4c1e8fca18 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/TypeNameHelper.cs @@ -0,0 +1,36 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Diagnostics.CodeAnalysis; + +namespace Microsoft.Extensions.Logging.Abstractions +{ + /// + /// Helper to process type names. + /// + public static class TypeNameHelper + { + /// + /// Gets the display name of a type from an instance. + /// + /// The instance. + /// to use the fully qualified name; otherwise . + /// The type display name. + [return: NotNullIfNotNull(nameof(item))] + public static string? GetTypeDisplayName(object? item, bool fullName = true) + => Microsoft.Extensions.Internal.TypeNameHelper.GetTypeDisplayName(item, fullName); + + /// + /// Pretty print a type name. + /// + /// The . + /// to print a fully qualified name. + /// to include generic parameter names. + /// to include generic parameters. + /// Character to use as a delimiter in nested type names. + /// The pretty printed type name. + public static string GetTypeDisplayName(Type type, bool fullName = true, bool includeGenericParameterNames = false, bool includeGenericParameters = true, char nestedTypeDelimiter = '+') + => Microsoft.Extensions.Internal.TypeNameHelper.GetTypeDisplayName(type, fullName, includeGenericParameterNames, includeGenericParameters, nestedTypeDelimiter); + } +} diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/TypeNameHelperObsolete.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/TypeNameHelperObsolete.cs new file mode 100644 index 00000000000000..010535cc1db192 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/TypeNameHelperObsolete.cs @@ -0,0 +1,26 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; + +namespace Microsoft.Extensions.Logging.Abstractions.Internal +{ + /// + /// Helper to process type names. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + [Obsolete("This type is retained only for compatibility. Do not use.", error: true)] + public static class TypeNameHelper + { + /// + [return: NotNullIfNotNull(nameof(item))] + public static string? GetTypeDisplayName(object? item, bool fullName = true) + => Abstractions.TypeNameHelper.GetTypeDisplayName(item, fullName); + + /// + public static string GetTypeDisplayName(Type type, bool fullName = true, bool includeGenericParameterNames = false, bool includeGenericParameters = true, char nestedTypeDelimiter = '+') + => Abstractions.TypeNameHelper.GetTypeDisplayName(type, fullName, includeGenericParameterNames, includeGenericParameters, nestedTypeDelimiter); + } +} diff --git a/src/libraries/Microsoft.Extensions.Logging/ref/Microsoft.Extensions.Logging.Forwards.cs b/src/libraries/Microsoft.Extensions.Logging/ref/Microsoft.Extensions.Logging.Forwards.cs index ac715dab79067f..1c197f62fc070e 100644 --- a/src/libraries/Microsoft.Extensions.Logging/ref/Microsoft.Extensions.Logging.Forwards.cs +++ b/src/libraries/Microsoft.Extensions.Logging/ref/Microsoft.Extensions.Logging.Forwards.cs @@ -6,3 +6,7 @@ [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Microsoft.Extensions.Logging.ILoggingBuilder))] [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Microsoft.Extensions.Logging.ProviderAliasAttribute))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Microsoft.Extensions.Logging.FormattedLogValues))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Microsoft.Extensions.Logging.LogValuesFormatter))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Microsoft.Extensions.Logging.Internal.FormattedLogValues))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Microsoft.Extensions.Logging.Internal.LogValuesFormatter))] diff --git a/src/libraries/Microsoft.Extensions.Logging/src/Properties/TypeForwards.cs b/src/libraries/Microsoft.Extensions.Logging/src/Properties/TypeForwards.cs index 659dd4ee6ca2f5..aba1620cf14fdb 100644 --- a/src/libraries/Microsoft.Extensions.Logging/src/Properties/TypeForwards.cs +++ b/src/libraries/Microsoft.Extensions.Logging/src/Properties/TypeForwards.cs @@ -3,3 +3,7 @@ [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Microsoft.Extensions.Logging.ILoggingBuilder))] [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Microsoft.Extensions.Logging.ProviderAliasAttribute))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Microsoft.Extensions.Logging.FormattedLogValues))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Microsoft.Extensions.Logging.LogValuesFormatter))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Microsoft.Extensions.Logging.Internal.FormattedLogValues))] +[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Microsoft.Extensions.Logging.Internal.LogValuesFormatter))] From e02c2db3930b33d2044bb24bb701aecc9607e5fc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Apr 2026 21:27:13 +0000 Subject: [PATCH 3/9] Rename NullScopeLogging.cs to NullScopeAbstractions.cs to match class location conventions Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/85535733-d8cc-4425-a106-63e3ccf52b70 Co-authored-by: ericstj <8918108+ericstj@users.noreply.github.com> --- .../src/{NullScopeLogging.cs => NullScopeAbstractions.cs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/libraries/Microsoft.Extensions.Logging.Abstractions/src/{NullScopeLogging.cs => NullScopeAbstractions.cs} (100%) diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/NullScopeLogging.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/NullScopeAbstractions.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Logging.Abstractions/src/NullScopeLogging.cs rename to src/libraries/Microsoft.Extensions.Logging.Abstractions/src/NullScopeAbstractions.cs From 2b952070874953235dce2402dcb653d899944dd6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Apr 2026 22:22:03 +0000 Subject: [PATCH 4/9] Remove non-obsolete public types; keep only the Internal obsolete shims Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/0590d250-7011-4a2b-822c-8e0a47df5fcd Co-authored-by: ericstj <8918108+ericstj@users.noreply.github.com> --- ...crosoft.Extensions.Logging.Abstractions.cs | 34 +----------------- .../src/FormattedLogValues.cs | 11 +----- .../src/LogValuesFormatter.cs | 19 +--------- .../src/LogValuesFormatterObsolete.cs | 10 +++--- .../src/NullScope.cs | 2 +- .../src/NullScopeAbstractions.cs | 27 -------------- .../src/TypeNameHelper.cs | 36 ------------------- .../src/TypeNameHelperObsolete.cs | 8 ++--- .../Microsoft.Extensions.Logging.Forwards.cs | 2 -- .../src/Properties/TypeForwards.cs | 2 -- 10 files changed, 13 insertions(+), 138 deletions(-) delete mode 100644 src/libraries/Microsoft.Extensions.Logging.Abstractions/src/NullScopeAbstractions.cs delete mode 100644 src/libraries/Microsoft.Extensions.Logging.Abstractions/src/TypeNameHelper.cs diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.cs index bbbef51491c7fa..ece60b1c4cf653 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.cs @@ -161,26 +161,6 @@ public partial class ProviderAliasAttribute : System.Attribute public ProviderAliasAttribute(string alias) { } public string Alias { get { throw null; } } } - public partial struct FormattedLogValues : System.Collections.Generic.IReadOnlyList>, System.Collections.Generic.IEnumerable>, System.Collections.IEnumerable, System.Collections.Generic.IReadOnlyCollection> - { - private readonly object _dummy; - private readonly int _dummyPrimitive; - public FormattedLogValues(string? format, params object?[]? values) { } - public System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } - public int Count { get { throw null; } } - public System.Collections.Generic.IEnumerator> GetEnumerator() { throw null; } - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } - public override string ToString() { throw null; } - } - public sealed partial class LogValuesFormatter - { - public LogValuesFormatter(string format) { } - public string OriginalFormat { get { throw null; } } - public System.Collections.Generic.List ValueNames { get { throw null; } } - public string Format(object?[]? values) { throw null; } - public System.Collections.Generic.KeyValuePair GetValue(object?[] values, int index) { throw null; } - public System.Collections.Generic.IEnumerable> GetValues(object[] values) { throw null; } - } } namespace Microsoft.Extensions.Logging.Abstractions { @@ -245,23 +225,11 @@ public interface IBufferedLogger { void LogRecords(System.Collections.Generic.IEnumerable records); } - public sealed partial class NullScope : System.IDisposable - { - private NullScope() { } - public static Microsoft.Extensions.Logging.Abstractions.NullScope Instance { get { throw null; } } - public void Dispose() { } - } - public static partial class TypeNameHelper - { - [return: System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute("item")] - public static string? GetTypeDisplayName(object? item, bool fullName = true) { throw null; } - public static string GetTypeDisplayName(System.Type type, bool fullName = true, bool includeGenericParameterNames = false, bool includeGenericParameters = true, char nestedTypeDelimiter = '+') { throw null; } - } } namespace Microsoft.Extensions.Logging.Abstractions.Internal { [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - [System.ObsoleteAttribute("This type is retained only for compatibility. The recommended alternative is NullScope in the Microsoft.Extensions.Logging.Abstractions namespace.", error: true)] + [System.ObsoleteAttribute("This type is retained only for compatibility. The recommended alternative is Microsoft.Extensions.Logging.NullScope.", error: true)] public partial class NullScope : System.IDisposable { private NullScope() { } diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/FormattedLogValues.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/FormattedLogValues.cs index f8214da89acf25..dd9d053a675710 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/FormattedLogValues.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/FormattedLogValues.cs @@ -14,7 +14,7 @@ namespace Microsoft.Extensions.Logging /// LogValues to enable formatting options supported by . /// This also enables using {NamedFormatItem} in the format string. /// - public struct FormattedLogValues : IReadOnlyList> + internal struct FormattedLogValues : IReadOnlyList> { internal const int MaxCachedFormatters = 1024; private const string NullFormat = "[null]"; @@ -30,11 +30,6 @@ public struct FormattedLogValues : IReadOnlyList> // for testing purposes internal LogValuesFormatter? Formatter => _formatter; - /// - /// Initializes a new instance of the struct. - /// - /// The named format string. - /// The values to substitute into the format string. public FormattedLogValues(string? format, params object?[]? values) { if (values != null && values.Length != 0 && format != null) @@ -65,7 +60,6 @@ public FormattedLogValues(string? format, params object?[]? values) _cachedToString = null; } - /// public KeyValuePair this[int index] { get @@ -84,7 +78,6 @@ public FormattedLogValues(string? format, params object?[]? values) } } - /// public int Count { get @@ -98,7 +91,6 @@ public int Count } } - /// public IEnumerator> GetEnumerator() { for (int i = 0; i < Count; ++i) @@ -107,7 +99,6 @@ public int Count } } - /// public override string ToString() { if (_formatter == null) diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LogValuesFormatter.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LogValuesFormatter.cs index 4437302b31f67a..2fdba83aa3206c 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LogValuesFormatter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LogValuesFormatter.cs @@ -13,7 +13,7 @@ namespace Microsoft.Extensions.Logging /// /// Formatter to convert the named format items like {NamedformatItem} to format. /// - public sealed class LogValuesFormatter + internal sealed class LogValuesFormatter { private const string NullValue = "(null)"; private readonly List _valueNames = new List(); @@ -27,10 +27,6 @@ public sealed class LogValuesFormatter // - Be annotated as [SkipLocalsInit] to avoid zero'ing the stackalloc'd char span // - Format _valueNames.Count directly into a span - /// - /// Initializes a new instance of the class. - /// - /// The named format string. public LogValuesFormatter(string format) { ArgumentNullException.ThrowIfNull(format); @@ -86,10 +82,7 @@ public LogValuesFormatter(string format) #endif } - /// Gets the original format string. public string OriginalFormat { get; } - - /// Gets the list of named format parameter names. public List ValueNames => _valueNames; private static int FindBraceIndex(string format, char brace, int startIndex, int endIndex) @@ -140,9 +133,6 @@ private static int FindBraceIndex(string format, char brace, int startIndex, int return braceIndex; } - /// Formats the given values using the format string. - /// The values to format. - /// The formatted string. public string Format(object?[]? values) { object?[]? formattedValues = values; @@ -228,10 +218,6 @@ internal string Format(object? arg0, object? arg1, object? arg2) => string.Format(CultureInfo.InvariantCulture, _format, FormatArgument(arg0), FormatArgument(arg1), FormatArgument(arg2)); #endif - /// Gets the key/value pair for the format item at the specified index. - /// The values array. - /// The index of the value to retrieve. - /// A key/value pair for the format item. public KeyValuePair GetValue(object?[] values, int index) { if (index < 0 || index > _valueNames.Count) @@ -247,9 +233,6 @@ internal string Format(object? arg0, object? arg1, object? arg2) => return new KeyValuePair("{OriginalFormat}", OriginalFormat); } - /// Gets an enumerable of key/value pairs for all format items. - /// The values array. - /// An enumerable of key/value pairs. public IEnumerable> GetValues(object[] values) { var valueArray = new KeyValuePair[values.Length + 1]; diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LogValuesFormatterObsolete.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LogValuesFormatterObsolete.cs index 3bddcdb7dc432e..8cce263a6c5065 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LogValuesFormatterObsolete.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LogValuesFormatterObsolete.cs @@ -25,19 +25,19 @@ public LogValuesFormatter(string format) _inner = new Microsoft.Extensions.Logging.LogValuesFormatter(format); } - /// + /// Gets the original format string. public string OriginalFormat => _inner.OriginalFormat; - /// + /// Gets the list of named format parameter names. public List ValueNames => _inner.ValueNames; - /// + /// Formats the given values using the format string. public string Format(object?[]? values) => _inner.Format(values); - /// + /// Gets the key/value pair for the format item at the specified index. public KeyValuePair GetValue(object?[] values, int index) => _inner.GetValue(values, index); - /// + /// Gets an enumerable of key/value pairs for all format items. public IEnumerable> GetValues(object[] values) => _inner.GetValues(values); } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/NullScope.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/NullScope.cs index 461a1551d73df8..b0d0dcaf239723 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/NullScope.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/NullScope.cs @@ -10,7 +10,7 @@ namespace Microsoft.Extensions.Logging.Abstractions.Internal /// An empty scope without any logic. /// [EditorBrowsable(EditorBrowsableState.Never)] - [Obsolete("This type is retained only for compatibility. The recommended alternative is NullScope in the Microsoft.Extensions.Logging.Abstractions namespace.", error: true)] + [Obsolete("This type is retained only for compatibility. The recommended alternative is Microsoft.Extensions.Logging.NullScope.", error: true)] public class NullScope : IDisposable { /// diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/NullScopeAbstractions.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/NullScopeAbstractions.cs deleted file mode 100644 index 88e47416c134bf..00000000000000 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/NullScopeAbstractions.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; - -namespace Microsoft.Extensions.Logging.Abstractions -{ - /// - /// An empty scope without any logic. - /// - public sealed class NullScope : IDisposable - { - /// - /// Returns the shared instance of . - /// - public static NullScope Instance { get; } = new NullScope(); - - private NullScope() - { - } - - /// - public void Dispose() - { - } - } -} diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/TypeNameHelper.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/TypeNameHelper.cs deleted file mode 100644 index 830b4c1e8fca18..00000000000000 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/TypeNameHelper.cs +++ /dev/null @@ -1,36 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Diagnostics.CodeAnalysis; - -namespace Microsoft.Extensions.Logging.Abstractions -{ - /// - /// Helper to process type names. - /// - public static class TypeNameHelper - { - /// - /// Gets the display name of a type from an instance. - /// - /// The instance. - /// to use the fully qualified name; otherwise . - /// The type display name. - [return: NotNullIfNotNull(nameof(item))] - public static string? GetTypeDisplayName(object? item, bool fullName = true) - => Microsoft.Extensions.Internal.TypeNameHelper.GetTypeDisplayName(item, fullName); - - /// - /// Pretty print a type name. - /// - /// The . - /// to print a fully qualified name. - /// to include generic parameter names. - /// to include generic parameters. - /// Character to use as a delimiter in nested type names. - /// The pretty printed type name. - public static string GetTypeDisplayName(Type type, bool fullName = true, bool includeGenericParameterNames = false, bool includeGenericParameters = true, char nestedTypeDelimiter = '+') - => Microsoft.Extensions.Internal.TypeNameHelper.GetTypeDisplayName(type, fullName, includeGenericParameterNames, includeGenericParameters, nestedTypeDelimiter); - } -} diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/TypeNameHelperObsolete.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/TypeNameHelperObsolete.cs index 010535cc1db192..1b7fd1fd40d6d9 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/TypeNameHelperObsolete.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/TypeNameHelperObsolete.cs @@ -14,13 +14,13 @@ namespace Microsoft.Extensions.Logging.Abstractions.Internal [Obsolete("This type is retained only for compatibility. Do not use.", error: true)] public static class TypeNameHelper { - /// + /// Gets the display name of a type from an instance. [return: NotNullIfNotNull(nameof(item))] public static string? GetTypeDisplayName(object? item, bool fullName = true) - => Abstractions.TypeNameHelper.GetTypeDisplayName(item, fullName); + => Microsoft.Extensions.Internal.TypeNameHelper.GetTypeDisplayName(item, fullName); - /// + /// Pretty prints a type name. public static string GetTypeDisplayName(Type type, bool fullName = true, bool includeGenericParameterNames = false, bool includeGenericParameters = true, char nestedTypeDelimiter = '+') - => Abstractions.TypeNameHelper.GetTypeDisplayName(type, fullName, includeGenericParameterNames, includeGenericParameters, nestedTypeDelimiter); + => Microsoft.Extensions.Internal.TypeNameHelper.GetTypeDisplayName(type, fullName, includeGenericParameterNames, includeGenericParameters, nestedTypeDelimiter); } } diff --git a/src/libraries/Microsoft.Extensions.Logging/ref/Microsoft.Extensions.Logging.Forwards.cs b/src/libraries/Microsoft.Extensions.Logging/ref/Microsoft.Extensions.Logging.Forwards.cs index 1c197f62fc070e..54d4eab69b2ca6 100644 --- a/src/libraries/Microsoft.Extensions.Logging/ref/Microsoft.Extensions.Logging.Forwards.cs +++ b/src/libraries/Microsoft.Extensions.Logging/ref/Microsoft.Extensions.Logging.Forwards.cs @@ -6,7 +6,5 @@ [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Microsoft.Extensions.Logging.ILoggingBuilder))] [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Microsoft.Extensions.Logging.ProviderAliasAttribute))] -[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Microsoft.Extensions.Logging.FormattedLogValues))] -[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Microsoft.Extensions.Logging.LogValuesFormatter))] [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Microsoft.Extensions.Logging.Internal.FormattedLogValues))] [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Microsoft.Extensions.Logging.Internal.LogValuesFormatter))] diff --git a/src/libraries/Microsoft.Extensions.Logging/src/Properties/TypeForwards.cs b/src/libraries/Microsoft.Extensions.Logging/src/Properties/TypeForwards.cs index aba1620cf14fdb..9d16e2abb33d04 100644 --- a/src/libraries/Microsoft.Extensions.Logging/src/Properties/TypeForwards.cs +++ b/src/libraries/Microsoft.Extensions.Logging/src/Properties/TypeForwards.cs @@ -3,7 +3,5 @@ [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Microsoft.Extensions.Logging.ILoggingBuilder))] [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Microsoft.Extensions.Logging.ProviderAliasAttribute))] -[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Microsoft.Extensions.Logging.FormattedLogValues))] -[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Microsoft.Extensions.Logging.LogValuesFormatter))] [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Microsoft.Extensions.Logging.Internal.FormattedLogValues))] [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Microsoft.Extensions.Logging.Internal.LogValuesFormatter))] From c449159ce942a6a601612ee9a33f3e6a8e148d45 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Apr 2026 23:52:39 +0000 Subject: [PATCH 5/9] Rename NullScope.cs to NullScopeObsolete.cs; remove unnecessary type forwards from Microsoft.Extensions.Logging Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/6df4e960-8c24-49ae-99ed-239b9771dc2d Co-authored-by: ericstj <8918108+ericstj@users.noreply.github.com> --- .../src/{NullScope.cs => NullScopeObsolete.cs} | 0 .../ref/Microsoft.Extensions.Logging.Forwards.cs | 2 -- .../Microsoft.Extensions.Logging/src/Properties/TypeForwards.cs | 2 -- 3 files changed, 4 deletions(-) rename src/libraries/Microsoft.Extensions.Logging.Abstractions/src/{NullScope.cs => NullScopeObsolete.cs} (100%) diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/NullScope.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/NullScopeObsolete.cs similarity index 100% rename from src/libraries/Microsoft.Extensions.Logging.Abstractions/src/NullScope.cs rename to src/libraries/Microsoft.Extensions.Logging.Abstractions/src/NullScopeObsolete.cs diff --git a/src/libraries/Microsoft.Extensions.Logging/ref/Microsoft.Extensions.Logging.Forwards.cs b/src/libraries/Microsoft.Extensions.Logging/ref/Microsoft.Extensions.Logging.Forwards.cs index 54d4eab69b2ca6..ac715dab79067f 100644 --- a/src/libraries/Microsoft.Extensions.Logging/ref/Microsoft.Extensions.Logging.Forwards.cs +++ b/src/libraries/Microsoft.Extensions.Logging/ref/Microsoft.Extensions.Logging.Forwards.cs @@ -6,5 +6,3 @@ [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Microsoft.Extensions.Logging.ILoggingBuilder))] [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Microsoft.Extensions.Logging.ProviderAliasAttribute))] -[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Microsoft.Extensions.Logging.Internal.FormattedLogValues))] -[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Microsoft.Extensions.Logging.Internal.LogValuesFormatter))] diff --git a/src/libraries/Microsoft.Extensions.Logging/src/Properties/TypeForwards.cs b/src/libraries/Microsoft.Extensions.Logging/src/Properties/TypeForwards.cs index 9d16e2abb33d04..659dd4ee6ca2f5 100644 --- a/src/libraries/Microsoft.Extensions.Logging/src/Properties/TypeForwards.cs +++ b/src/libraries/Microsoft.Extensions.Logging/src/Properties/TypeForwards.cs @@ -3,5 +3,3 @@ [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Microsoft.Extensions.Logging.ILoggingBuilder))] [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Microsoft.Extensions.Logging.ProviderAliasAttribute))] -[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Microsoft.Extensions.Logging.Internal.FormattedLogValues))] -[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(Microsoft.Extensions.Logging.Internal.LogValuesFormatter))] From 140dbb89dbaa51e086f58d49cfbc88fc5d2b596a Mon Sep 17 00:00:00 2001 From: "Eric St. John" Date: Mon, 20 Apr 2026 19:19:07 -0700 Subject: [PATCH 6/9] Make API compatible with 2.1 Logging.Abstractiosn --- .../ref/Microsoft.Extensions.Logging.Abstractions.cs | 8 +++----- .../src/FormattedLogValuesObsolete.cs | 2 +- .../src/LogValuesFormatterObsolete.cs | 2 +- .../src/TypeNameHelperObsolete.cs | 11 +++-------- 4 files changed, 8 insertions(+), 15 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.cs index ece60b1c4cf653..1d4e288744b942 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.cs @@ -232,7 +232,7 @@ namespace Microsoft.Extensions.Logging.Abstractions.Internal [System.ObsoleteAttribute("This type is retained only for compatibility. The recommended alternative is Microsoft.Extensions.Logging.NullScope.", error: true)] public partial class NullScope : System.IDisposable { - private NullScope() { } + internal NullScope() { } public static Microsoft.Extensions.Logging.Abstractions.Internal.NullScope Instance { get { throw null; } } public void Dispose() { } } @@ -240,8 +240,6 @@ public void Dispose() { } [System.ObsoleteAttribute("This type is retained only for compatibility. Do not use.", error: true)] public static partial class TypeNameHelper { - [return: System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute("item")] - public static string? GetTypeDisplayName(object? item, bool fullName = true) { throw null; } public static string GetTypeDisplayName(System.Type type, bool fullName = true, bool includeGenericParameterNames = false, bool includeGenericParameters = true, char nestedTypeDelimiter = '+') { throw null; } } } @@ -249,11 +247,11 @@ namespace Microsoft.Extensions.Logging.Internal { [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] [System.ObsoleteAttribute("This type is retained only for compatibility. The recommended alternative is Microsoft.Extensions.Diagnostics.Testing.", error: true)] - public sealed partial class FormattedLogValues : System.Collections.Generic.IReadOnlyList>, System.Collections.Generic.IEnumerable>, System.Collections.IEnumerable, System.Collections.Generic.IReadOnlyCollection> + public sealed partial class FormattedLogValues : System.Collections.Generic.IEnumerable>, System.Collections.Generic.IReadOnlyCollection>, System.Collections.Generic.IReadOnlyList>, System.Collections.IEnumerable { public FormattedLogValues(string? format, params object?[]? values) { } - public System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } public int Count { get { throw null; } } + public System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } public System.Collections.Generic.IEnumerator> GetEnumerator() { throw null; } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } public override string ToString() { throw null; } diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/FormattedLogValuesObsolete.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/FormattedLogValuesObsolete.cs index 4a60475e4d65a3..889717fe687f18 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/FormattedLogValuesObsolete.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/FormattedLogValuesObsolete.cs @@ -14,7 +14,7 @@ namespace Microsoft.Extensions.Logging.Internal /// [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("This type is retained only for compatibility. The recommended alternative is Microsoft.Extensions.Diagnostics.Testing.", error: true)] - public sealed class FormattedLogValues : IReadOnlyList> + public class FormattedLogValues : IReadOnlyList> { private readonly Microsoft.Extensions.Logging.FormattedLogValues _inner; diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LogValuesFormatterObsolete.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LogValuesFormatterObsolete.cs index 8cce263a6c5065..500b19aa6d26c0 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LogValuesFormatterObsolete.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LogValuesFormatterObsolete.cs @@ -12,7 +12,7 @@ namespace Microsoft.Extensions.Logging.Internal /// [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("This type is retained only for compatibility. The recommended alternative is Microsoft.Extensions.Diagnostics.Testing.", error: true)] - public sealed class LogValuesFormatter + public class LogValuesFormatter { private readonly Microsoft.Extensions.Logging.LogValuesFormatter _inner; diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/TypeNameHelperObsolete.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/TypeNameHelperObsolete.cs index 1b7fd1fd40d6d9..043311342de3fd 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/TypeNameHelperObsolete.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/TypeNameHelperObsolete.cs @@ -12,15 +12,10 @@ namespace Microsoft.Extensions.Logging.Abstractions.Internal /// [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("This type is retained only for compatibility. Do not use.", error: true)] - public static class TypeNameHelper + public class TypeNameHelper { - /// Gets the display name of a type from an instance. - [return: NotNullIfNotNull(nameof(item))] - public static string? GetTypeDisplayName(object? item, bool fullName = true) - => Microsoft.Extensions.Internal.TypeNameHelper.GetTypeDisplayName(item, fullName); - /// Pretty prints a type name. - public static string GetTypeDisplayName(Type type, bool fullName = true, bool includeGenericParameterNames = false, bool includeGenericParameters = true, char nestedTypeDelimiter = '+') - => Microsoft.Extensions.Internal.TypeNameHelper.GetTypeDisplayName(type, fullName, includeGenericParameterNames, includeGenericParameters, nestedTypeDelimiter); + public static string GetTypeDisplayName(Type type) + => Microsoft.Extensions.Internal.TypeNameHelper.GetTypeDisplayName(type); } } From 06cd5ece672c76af8431c5ae76e7a226f1011d15 Mon Sep 17 00:00:00 2001 From: "Eric St. John" Date: Mon, 20 Apr 2026 19:47:03 -0700 Subject: [PATCH 7/9] Fix ref --- .../ref/Microsoft.Extensions.Logging.Abstractions.cs | 10 +++++----- .../src/TypeNameHelperObsolete.cs | 1 - 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.cs index 1d4e288744b942..00a12caf735633 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.cs @@ -232,22 +232,22 @@ namespace Microsoft.Extensions.Logging.Abstractions.Internal [System.ObsoleteAttribute("This type is retained only for compatibility. The recommended alternative is Microsoft.Extensions.Logging.NullScope.", error: true)] public partial class NullScope : System.IDisposable { - internal NullScope() { } + private NullScope() { } public static Microsoft.Extensions.Logging.Abstractions.Internal.NullScope Instance { get { throw null; } } public void Dispose() { } } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] [System.ObsoleteAttribute("This type is retained only for compatibility. Do not use.", error: true)] - public static partial class TypeNameHelper + public partial class TypeNameHelper { - public static string GetTypeDisplayName(System.Type type, bool fullName = true, bool includeGenericParameterNames = false, bool includeGenericParameters = true, char nestedTypeDelimiter = '+') { throw null; } + public static string GetTypeDisplayName(System.Type type) { throw null; } } } namespace Microsoft.Extensions.Logging.Internal { [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] [System.ObsoleteAttribute("This type is retained only for compatibility. The recommended alternative is Microsoft.Extensions.Diagnostics.Testing.", error: true)] - public sealed partial class FormattedLogValues : System.Collections.Generic.IEnumerable>, System.Collections.Generic.IReadOnlyCollection>, System.Collections.Generic.IReadOnlyList>, System.Collections.IEnumerable + public partial class FormattedLogValues : System.Collections.Generic.IEnumerable>, System.Collections.Generic.IReadOnlyCollection>, System.Collections.Generic.IReadOnlyList>, System.Collections.IEnumerable { public FormattedLogValues(string? format, params object?[]? values) { } public int Count { get { throw null; } } @@ -258,7 +258,7 @@ public FormattedLogValues(string? format, params object?[]? values) { } } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] [System.ObsoleteAttribute("This type is retained only for compatibility. The recommended alternative is Microsoft.Extensions.Diagnostics.Testing.", error: true)] - public sealed partial class LogValuesFormatter + public partial class LogValuesFormatter { public LogValuesFormatter(string format) { } public string OriginalFormat { get { throw null; } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/TypeNameHelperObsolete.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/TypeNameHelperObsolete.cs index 043311342de3fd..e2a90717de9420 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/TypeNameHelperObsolete.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/TypeNameHelperObsolete.cs @@ -3,7 +3,6 @@ using System; using System.ComponentModel; -using System.Diagnostics.CodeAnalysis; namespace Microsoft.Extensions.Logging.Abstractions.Internal { From 8aa478eb11a4dfb459bd8eedf34387c92aa07731 Mon Sep 17 00:00:00 2001 From: "Eric St. John" Date: Mon, 20 Apr 2026 19:54:44 -0700 Subject: [PATCH 8/9] Adjust obsolete messages --- .../ref/Microsoft.Extensions.Logging.Abstractions.cs | 8 ++++---- .../src/FormattedLogValuesObsolete.cs | 2 +- .../src/LogValuesFormatterObsolete.cs | 2 +- .../src/NullScopeObsolete.cs | 2 +- .../src/TypeNameHelperObsolete.cs | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.cs index 00a12caf735633..9b833bb16a4ce0 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/ref/Microsoft.Extensions.Logging.Abstractions.cs @@ -229,7 +229,7 @@ public interface IBufferedLogger namespace Microsoft.Extensions.Logging.Abstractions.Internal { [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - [System.ObsoleteAttribute("This type is retained only for compatibility. The recommended alternative is Microsoft.Extensions.Logging.NullScope.", error: true)] + [System.ObsoleteAttribute("This type is retained only for compatibility.", error: true)] public partial class NullScope : System.IDisposable { private NullScope() { } @@ -237,7 +237,7 @@ private NullScope() { } public void Dispose() { } } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - [System.ObsoleteAttribute("This type is retained only for compatibility. Do not use.", error: true)] + [System.ObsoleteAttribute("This type is retained only for compatibility.", error: true)] public partial class TypeNameHelper { public static string GetTypeDisplayName(System.Type type) { throw null; } @@ -246,7 +246,7 @@ public partial class TypeNameHelper namespace Microsoft.Extensions.Logging.Internal { [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - [System.ObsoleteAttribute("This type is retained only for compatibility. The recommended alternative is Microsoft.Extensions.Diagnostics.Testing.", error: true)] + [System.ObsoleteAttribute("This type is retained only for compatibility. The recommended alternative is the Microsoft.Extensions.Diagnostics.Testing package.", error: true)] public partial class FormattedLogValues : System.Collections.Generic.IEnumerable>, System.Collections.Generic.IReadOnlyCollection>, System.Collections.Generic.IReadOnlyList>, System.Collections.IEnumerable { public FormattedLogValues(string? format, params object?[]? values) { } @@ -257,7 +257,7 @@ public FormattedLogValues(string? format, params object?[]? values) { } public override string ToString() { throw null; } } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - [System.ObsoleteAttribute("This type is retained only for compatibility. The recommended alternative is Microsoft.Extensions.Diagnostics.Testing.", error: true)] + [System.ObsoleteAttribute("This type is retained only for compatibility. The recommended alternative is the Microsoft.Extensions.Diagnostics.Testing package.", error: true)] public partial class LogValuesFormatter { public LogValuesFormatter(string format) { } diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/FormattedLogValuesObsolete.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/FormattedLogValuesObsolete.cs index 889717fe687f18..23de1790a2f7cd 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/FormattedLogValuesObsolete.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/FormattedLogValuesObsolete.cs @@ -13,7 +13,7 @@ namespace Microsoft.Extensions.Logging.Internal /// This also enables using {NamedFormatItem} in the format string. /// [EditorBrowsable(EditorBrowsableState.Never)] - [Obsolete("This type is retained only for compatibility. The recommended alternative is Microsoft.Extensions.Diagnostics.Testing.", error: true)] + [Obsolete("This type is retained only for compatibility. The recommended alternative is the Microsoft.Extensions.Diagnostics.Testing package.", error: true)] public class FormattedLogValues : IReadOnlyList> { private readonly Microsoft.Extensions.Logging.FormattedLogValues _inner; diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LogValuesFormatterObsolete.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LogValuesFormatterObsolete.cs index 500b19aa6d26c0..2cb2c1475513bf 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LogValuesFormatterObsolete.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LogValuesFormatterObsolete.cs @@ -11,7 +11,7 @@ namespace Microsoft.Extensions.Logging.Internal /// Formatter to convert the named format items like {NamedformatItem} to format. /// [EditorBrowsable(EditorBrowsableState.Never)] - [Obsolete("This type is retained only for compatibility. The recommended alternative is Microsoft.Extensions.Diagnostics.Testing.", error: true)] + [Obsolete("This type is retained only for compatibility. The recommended alternative is the Microsoft.Extensions.Diagnostics.Testing package.", error: true)] public class LogValuesFormatter { private readonly Microsoft.Extensions.Logging.LogValuesFormatter _inner; diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/NullScopeObsolete.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/NullScopeObsolete.cs index b0d0dcaf239723..3a40e0d83cab7e 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/NullScopeObsolete.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/NullScopeObsolete.cs @@ -10,7 +10,7 @@ namespace Microsoft.Extensions.Logging.Abstractions.Internal /// An empty scope without any logic. /// [EditorBrowsable(EditorBrowsableState.Never)] - [Obsolete("This type is retained only for compatibility. The recommended alternative is Microsoft.Extensions.Logging.NullScope.", error: true)] + [Obsolete("This type is retained only for compatibility.", error: true)] public class NullScope : IDisposable { /// diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/TypeNameHelperObsolete.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/TypeNameHelperObsolete.cs index e2a90717de9420..5c6fbe7aada6d5 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/TypeNameHelperObsolete.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/TypeNameHelperObsolete.cs @@ -10,7 +10,7 @@ namespace Microsoft.Extensions.Logging.Abstractions.Internal /// Helper to process type names. /// [EditorBrowsable(EditorBrowsableState.Never)] - [Obsolete("This type is retained only for compatibility. Do not use.", error: true)] + [Obsolete("This type is retained only for compatibility.", error: true)] public class TypeNameHelper { /// Pretty prints a type name. From 058c15097422a6dd1206cdb8cbcc5181e59c9c11 Mon Sep 17 00:00:00 2001 From: Eric StJohn Date: Tue, 21 Apr 2026 12:15:15 -0700 Subject: [PATCH 9/9] Apply suggestions from code review Co-authored-by: Eric StJohn --- .../src/FormattedLogValuesObsolete.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/FormattedLogValuesObsolete.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/FormattedLogValuesObsolete.cs index 23de1790a2f7cd..179e251bb9de91 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/FormattedLogValuesObsolete.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/FormattedLogValuesObsolete.cs @@ -16,7 +16,7 @@ namespace Microsoft.Extensions.Logging.Internal [Obsolete("This type is retained only for compatibility. The recommended alternative is the Microsoft.Extensions.Diagnostics.Testing package.", error: true)] public class FormattedLogValues : IReadOnlyList> { - private readonly Microsoft.Extensions.Logging.FormattedLogValues _inner; + private Microsoft.Extensions.Logging.FormattedLogValues _inner; /// /// Initializes a new instance of the class.