.NET Core 3.0 has just been released, see here the official announcement. In this post we’re going to explain how to list and explore the new APIs introduced since .NET Core 2.2 (this API diff is also available here).

To diff the API versions download NDepend trial, start VisualNDepend.exe, and click Compare 2 versions of a code base.

In the Older Build add assemblies in the folder: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\2.2.5

In the Newer Build add assemblies in the folder: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.0.0

Then click OK. Depending on your hardware it’ll take between a dozen of seconds and a minute to analyze these two versions of .NET Core.

Here are the lists of new APIs obtained:

To obtain these lists we’ve edited 5 code queries and exported their results to HTML. For example to obtain the 28 new namespaces we edited the query:

// <Name>New .NET Core 3.0 API Namespaces</Name> let olderNamespacesFullNames = codeBase.OlderVersion().Application.Namespaces.Select(m => m.FullName).ToHashSetEx() from n in Application.Namespaces where n.IsPublic // We want namespaces that contain at least one public type && !olderNamespacesFullNames.Contains(n.FullName) select new { n, publicTypes = n.ChildTypes.Where(t => t.IsPublic) } 1 2 3 4 5 6 7 8 9 10 // <Name>New .NET Core 3.0 API Namespaces</Name> let olderNamespacesFullNames = codeBase . OlderVersion ( ) . Application . Namespaces . Select ( m = > m . FullName ) . ToHashSetEx ( ) from n in Application . Namespaces where n . IsPublic // We want namespaces that contain at least one public type && ! olderNamespacesFullNames . Contains ( n . FullName ) select new { n , publicTypes = n . ChildTypes . Where ( t = > t . IsPublic ) }

And got this result, that also lists new types for each new namespace:

The 4 others code queries used to list new types, new types and their members and new methods and new fields introduced in existing types are:

// <Name>New .NET Core 3.0 API Types</Name> let olderTypesFullNames = codeBase.OlderVersion().Application.Types.Select(m => m.FullName).ToHashSetEx() from t in Application.Types where t.IsPubliclyVisible // we want only public API && !olderTypesFullNames.Contains(t.FullName) select new { t, publicMembers = t.Members.Where(m => m.IsPubliclyVisible) } 1 2 3 4 5 6 7 8 9 10 // <Name>New .NET Core 3.0 API Types</Name> let olderTypesFullNames = codeBase . OlderVersion ( ) . Application . Types . Select ( m = > m . FullName ) . ToHashSetEx ( ) from t in Application . Types where t . IsPubliclyVisible // we want only public API && ! olderTypesFullNames . Contains ( t . FullName ) select new { t , publicMembers = t . Members . Where ( m = > m . IsPubliclyVisible ) }

// <Name>New .NET Core 3.0 API Types and their Members</Name> let olderTypesFullNames = codeBase.OlderVersion().Application.Types.Select(m => m.FullName).ToHashSetEx() from t in Application.Types where t.IsPubliclyVisible // we want only public API && !olderTypesFullNames.Contains(t.FullName) from x in t.Concat(t.Members.Where(m => m.IsPubliclyVisible)) select x 1 2 3 4 5 6 7 8 9 // <Name>New .NET Core 3.0 API Types and their Members</Name> let olderTypesFullNames = codeBase . OlderVersion ( ) . Application . Types . Select ( m = > m . FullName ) . ToHashSetEx ( ) from t in Application . Types where t . IsPubliclyVisible // we want only public API && ! olderTypesFullNames . Contains ( t . FullName ) from x in t . Concat ( t . Members . Where ( m = > m . IsPubliclyVisible ) ) select x

// <Name>New .NET Core 3.0 public methods in existing types</Name> let olderMethodsFullNames = codeBase.OlderVersion().Application.Methods.Select(m => m.FullName).ToHashSetEx() from m in Application.Methods where m.IsPubliclyVisible // we want only public API && m.WasAdded() // added since baseline (which is .NET Core 2.2.5) && !m.ParentType.WasAdded() // in existing type // Don't match methods moved from one assembly to another one && !olderMethodsFullNames.Contains(m.FullName) select m 1 2 3 4 5 6 7 8 9 10 11 // <Name>New .NET Core 3.0 public methods in existing types</Name> let olderMethodsFullNames = codeBase . OlderVersion ( ) . Application . Methods . Select ( m = > m . FullName ) . ToHashSetEx ( ) from m in Application . Methods where m . IsPubliclyVisible // we want only public API && m . WasAdded ( ) // added since baseline (which is .NET Core 2.2.5) && ! m . ParentType . WasAdded ( ) // in existing type // Don't match methods moved from one assembly to another one && ! olderMethodsFullNames . Contains ( m . FullName ) select m

// <Name>New .NET Core 3.0 public fields in existing types</Name> let olderFieldsFullNames = codeBase.OlderVersion().Application.Fields.Select(m => m.FullName).ToHashSetEx() from f in Application.Fields where f.IsPubliclyVisible // we want only public API && f.WasAdded() // added since baseline (which is .NET Core 2.2.5) && !f.ParentType.WasAdded() // in existing type // Don't match methods moved from one assembly to another one && !olderFieldsFullNames.Contains(f.FullName) select f 1 2 3 4 5 6 7 8 9 10 11 // <Name>New .NET Core 3.0 public fields in existing types</Name> let olderFieldsFullNames = codeBase . OlderVersion ( ) . Application . Fields . Select ( m = > m . FullName ) . ToHashSetEx ( ) from f in Application . Fields where f . IsPubliclyVisible // we want only public API && f . WasAdded ( ) // added since baseline (which is .NET Core 2.2.5) && ! f . ParentType . WasAdded ( ) // in existing type // Don't match methods moved from one assembly to another one && ! olderFieldsFullNames . Contains ( f . FullName ) select f