Skip to content

[Breaking change]: .NET 11+ shared framework includes Microsoft.Extensions.* Abstractions/Options/Primitives packages #52865

@ericstj

Description

@ericstj

Description

In .NET 11 and later, nine Microsoft.Extensions.* libraries (Abstractions, Options, and Primitives) are now included in the base shared framework (see PR dotnet/dotnet#5206 and final decision in dotnet/runtime#67487). This means:

  • PackageReference to these libraries is no longer required when targeting .NET 11+.
  • If you reference these packages on .NET 11+, you'll see a build warning (NU1510) that you can remove by deleting the PackageReference.
  • In rare cases, new name/type conflicts could occur if you have source or full type names that shadow new APIs now present in the base shared framework.
  • Self-contained applications which don't enable trimming may grow in size. Framework-dependent applications may shrink. AOT and trimmed applications should remain unchanged.

Links:

Version

.NET 11 Preview 4

Previous behavior

Before .NET 11, the following Microsoft.Extensions.* libraries were not present in the base shared framework and were required as PackageReferences in projects that needed them. Their absence from the shared framework meant their assemblies would routinely be copied to the output folder when packages referenced.

Packages:

  • Microsoft.Extensions.Caching.Abstractions
  • Microsoft.Extensions.Configuration.Abstractions
  • Microsoft.Extensions.DependencyInjection.Abstractions
  • Microsoft.Extensions.Diagnostics.Abstractions
  • Microsoft.Extensions.FileProviders.Abstractions
  • Microsoft.Extensions.Hosting.Abstractions
  • Microsoft.Extensions.Logging.Abstractions
  • Microsoft.Extensions.Options
  • Microsoft.Extensions.Primitives

New behavior

On .NET 11 or newer, these nine libraries are part of the base shared framework:

  • You'll receive warning NU1510 if you reference these packages explicitly (see link above).
  • To resolve NU1510, simply remove the PackageReference (the library is now always present).
  • These assemblies will no longer be copied to your output folder since the framework provides them.
  • In rare cases, more APIs in the default load set may result in source/type name conflicts; typical resolutions involve more explicit using directives or aliases.

Type of breaking change

  • Binary incompatible: Existing binaries might encounter a breaking change in behavior, such as failure to load or execute, and if so, require recompilation.
  • Source incompatible: When recompiled using the new SDK or component or to target the new runtime, existing source code might require source changes to compile successfully.
  • Behavioral change: Existing binaries might behave differently at run time.

Reason for change

Reduce application size, package dependencies, servicing when depending on these commonly used libraries.

Recommended action

  • If you see warning NU1510 for these Microsoft.Extensions packages, remove the PackageReference (not the warning). Your code should continue to work as before, as the APIs are now present in the runtime.
  • If you hit a compile-time name conflict (rare): resolve it with a more explicit using directive, an alias, or a fully qualified type name as needed.
  • If you were including these assemblies in your deployment of your framework dependent application, they are no longer required.
  • No other migration steps should be required for the vast majority of applications.

Past breaking changes

This change will effectively update the components mentioned to their latest 11.0 version. Many of these packages have made breaking changes between 1.0 and 11. When upgrading to abstractions/options packages to .NET 11, binaries compiled against older packages may fail at runtime with MissingMethodException or TypeLoadException if they depend on legacy member shapes or custom implementations of old interfaces. Update package references that contain legacy API usage to current package versions; for customer/custom implementations, recompile against the latest abstractions/options packages and implement the current public interface contract.

Breaking change Introduced in transition Exception type Exception message Required action
IConfigurationBuilder.Sources return type changed from IEnumerable<IConfigurationSource> to IList<IConfigurationSource>. 1.1 -> 2.0 MissingMethodException Method not found: System.Collections.Generic.IEnumerable1<Microsoft.Extensions.Configuration.IConfigurationSource> Microsoft.Extensions.Configuration.ConfigurationBuilder.get_Sources()`. Update package references containing legacy configuration builder usage to modern Microsoft.Extensions.Configuration.Abstractions/Microsoft.Extensions.Configuration (move off 1.1.x).
IConfigurationBuilder.Properties property return type changed from Dictionary<string, object> (concrete) to IDictionary<string, object> (interface). Also, property added to interface in 2.0 that did not exist in 1.1. 1.1 -> 2.0 MissingMethodException Method not found: System.Collections.Generic.Dictionary2<System.String,System.Object> Microsoft.Extensions.Configuration.ConfigurationBuilder.get_Properties()`. Update the package that references legacy ConfigurationBuilder member signatures to latest compatible configuration packages.
ICacheEntry.Size property (type long?) added to interface in 2.0; concrete CacheEntry implementation missing this required property. 1.1 -> 2.0 TypeLoadException Method get_Size in type Microsoft.Extensions.Caching.Memory.CacheEntry from assembly Microsoft.Extensions.Caching.Memory, Version=1.1.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60 does not have an implementation. Update Microsoft.Extensions.Caching.Abstractions and Microsoft.Extensions.Caching.Memory package references from 1.1.x baseline to latest compatible version.
HostBuilderContext.HostingEnvironment property return type changed from IHostingEnvironment to IHostEnvironment in 3.0. 2.1 -> 3.0 MissingMethodException Method not found: Microsoft.Extensions.Hosting.IHostingEnvironment Microsoft.Extensions.Hosting.HostBuilderContext.get_HostingEnvironment(). Update hosting package references (Microsoft.Extensions.Hosting.Abstractions / hosting stack) to consistent modern version; update code expecting IHostingEnvironment to work with IHostEnvironment interface.
OptionsWrapper<T> methods Add(string, T), Get(string), and Remove(string), introduced in 2.0, obsolete in 2.1, removed in 3.0. 2.1 -> 3.0 MissingMethodException Method not found: Void Microsoft.Extensions.Options.OptionsWrapper1.Add(System.String, !0)`. Update Microsoft.Extensions.Options package in projects using named OptionsWrapper methods and migrate to supported named options patterns via IOptionsMonitor<T> or IOptionsSnapshot<T>.
OptionsManager<T> and OptionsMonitor<T> constructors changed signature or removed in 2.0. OptionsManager<T>.ctor(IEnumerable<IConfigureOptions<T>>) and OptionsMonitor<T>.ctor(IEnumerable<IConfigureOptions<T>>, IEnumerable<IOptionsChangeTokenSource<T>>) no longer present. 1.1 -> 2.0 MissingMethodException Method not found: Void Microsoft.Extensions.Options.OptionsManager1..ctor(System.Collections.Generic.IEnumerable1<Microsoft.Extensions.Options.IConfigureOptions1<!0>>)`. Update package containing references to old concrete options types to latest Microsoft.Extensions.Options; prefer abstractions (IOptions* interfaces) over direct instantiation of concrete types.
IDistributedCache implementation compiled against 1.1 missing methods added in 2.0: GetAsync(string, CancellationToken), SetAsync(string, byte[], DistributedCacheEntryOptions, CancellationToken), RefreshAsync(string, CancellationToken), RemoveAsync(string, CancellationToken). 1.1 -> 2.0 TypeLoadException Method GetAsync in type MyDistributedCache from assembly UserAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null does not have an implementation. Recompile custom implementation assembly against latest Microsoft.Extensions.Caching.Abstractions and implement all required members in current IDistributedCache interface contract.
IOptionsMonitor<T> implementation compiled against 1.1 missing methods added in 2.0: Get(string) returning T, and OnChange(Action<T, string>) method overload (2.0 has two overloads with different signatures). 1.1 -> 2.0 TypeLoadException Method Get in type MyOptionsMonitor from assembly UserAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null does not have an implementation. Recompile custom implementation assembly against latest Microsoft.Extensions.Options and implement all members in current IOptionsMonitor<T> interface contract.
IOptionsSnapshot<T> implementation compiled against 1.1 missing method added in 2.0: Get(string) returning T. 1.1 -> 2.0 TypeLoadException Method Get in type MyOptionsSnapshot from assembly UserAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null does not have an implementation. Recompile custom implementation assembly against latest Microsoft.Extensions.Options and implement all members in current IOptionsSnapshot<T> interface contract.
IOptionsChangeTokenSource<T> implementation compiled against 1.1 missing property added in 2.0: Name (type string). 1.1 -> 2.0 TypeLoadException Method get_Name in type MyOptionsChangeTokenSource from assembly UserAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null does not have an implementation. Recompile custom implementation assembly against latest Microsoft.Extensions.Options and implement all members in current IOptionsChangeTokenSource<T> interface contract.
IConfigurationRoot implementation compiled against 1.1 missing property added in 2.0: Providers (type IEnumerable<IConfigurationProvider>). 1.1 -> 2.0 TypeLoadException Method get_Providers in type MyConfigurationRoot from assembly UserAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null does not have an implementation. Recompile custom implementation assembly against latest Microsoft.Extensions.Configuration.Abstractions and implement all members in current IConfigurationRoot interface contract.
ServiceCollection moved from DependencyInjection to DependencyInjection.Abstractions causes compilation error due to duplicate type. 5.0 -> 6.0 CS0433 The type 'ServiceCollection' exists in both 'Microsoft.Extensions.DependencyInjection.Abstractions, Version=11.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' and 'Microsoft.Extensions.DependencyInjection, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. Recompile custom implementation assembly against latest Microsoft.Extensions.Configuration.Abstractions and implement all members in current IConfigurationRoot interface contract.

Feature area

Core .NET libraries

Affected APIs

  • Microsoft.Extensions.Caching.Abstractions
  • Microsoft.Extensions.Configuration.Abstractions
  • Microsoft.Extensions.DependencyInjection.Abstractions
  • Microsoft.Extensions.Diagnostics.Abstractions
  • Microsoft.Extensions.FileProviders.Abstractions
  • Microsoft.Extensions.Hosting.Abstractions
  • Microsoft.Extensions.Logging.Abstractions
  • Microsoft.Extensions.Options
  • Microsoft.Extensions.Primitives

Associated WorkItem - 567074

Metadata

Metadata

Labels

📌 seQUESTeredIdentifies that an issue has been imported into Quest.breaking-changeIndicates a .NET Core breaking change

Type

No type
No fields configured for issues without a type.

Projects

Status

👀 In review

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions