eShop
C#Microsoft's reference .NET microservices application (ASP.NET Core, gRPC, .NET MAUI)
The new C# analyzer reads eShop's 28 projects with the Roslyn compiler's semantic model, without building or restoring anything: every declared type matches an independent count, and 56% of the C# calls that could reach the repository resolve to a declaration in it.
Call resolution (7,423 call sites)
- Resolved in the repository
- 1,021
- To libraries or the standard library
- 5,682
- Ambiguous (several possible targets)
- 23
- Unresolved (could be repo code)
- 697
The rate above is resolved ÷ (resolved + ambiguous + unresolved). Calls to libraries and the standard library cannot reach this repository, so they are shown separately and left out of it. Test code is included in these counts.
What the analysis shows
A separate scan of the source for class, interface, record, struct and enum declarations (comments and string contents removed) finds the same types as the analyzer in every one of the 547 C# files: 575 declarations.
7,040 C# call sites; 905 resolve to a method or constructor declared in the repository, through overloads, extension methods, generics and project references. Nothing in the repository is built or executed: project files are read as data, and the .NET reference assemblies come with the analyzer.
Calls into NuGet packages (Entity Framework, MediatR, Aspire and others) cannot be bound by the compiler, because the analyzer never restores packages. 3,631 calls whose method name no class of the repository declares are counted as calls to library code. 262 more (38% of the unresolved ones) are marked as missing dependencies rather than guessed, because a method of that name exists in the repository.
The ASP.NET Core adapter records 17 route handlers (3 with an exact path), 30 dependency-injection registrations and 15 program entry points.
The catalog, ordering and webhooks APIs register their endpoints on route groups created by the Asp.Versioning package (NewVersionedApi, HasApiVersion). Without that package the calls cannot be bound to ASP.NET Core, so their 31 literal Map… registrations are reported as unproven rather than as routes: the analyzer lists a registration only when the compiler proves it.
Largest cycle group
- src/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs
- src/Ordering.Domain/Events/OrderCancelledDomainEvent.cs
- src/Ordering.Domain/Events/OrderShippedDomainEvent.cs
- src/Ordering.Domain/Events/OrderStartedDomainEvent.cs
Most widely called symbols (calling files)
- src/Ordering.Domain/AggregatesModel/OrderAggregate/IOrderRepository.cs#eShop.Ordering.Domain.AggregatesModel.OrderAggregate.IOrderRepository.GetAsync (12)
- src/eShop.ServiceDefaults/Extensions.cs#eShop.ServiceDefaults.Extensions.MapDefaultEndpoints (9)
- src/Ordering.Domain/SeedWork/IUnitOfWork.cs#eShop.Ordering.Domain.Seedwork.IUnitOfWork.SaveEntitiesAsync (8)
- src/ClientApp/Services/Navigation/INavigationService.cs#eShop.ClientApp.Services.INavigationService.NavigateToAsync (7)
- src/eShop.ServiceDefaults/Extensions.cs#eShop.ServiceDefaults.Extensions.AddServiceDefaults (7)
- src/ClientApp/ViewModels/Base/ViewModelBase.cs#eShop.ClientApp.ViewModels.Base.ViewModelBase.IsBusyFor (6)
Endpoints (first rows of the inventory)
- GET /{conventional} -> src/Identity.API/Quickstart/Account/AccountController.cs#IdentityServerHost.Quickstart.UI.AccountController.AccessDenied
- POST /{conventional} -> src/Identity.API/Quickstart/Account/AccountController.cs#IdentityServerHost.Quickstart.UI.AccountController.Login(IdentityServerHost.Quickstart.UI.LoginInputModel,System.String)
- GET /{conventional} -> src/Identity.API/Quickstart/Account/AccountController.cs#IdentityServerHost.Quickstart.UI.AccountController.Login(System.String)
- POST /{conventional} -> src/Identity.API/Quickstart/Account/AccountController.cs#IdentityServerHost.Quickstart.UI.AccountController.Logout(IdentityServerHost.Quickstart.UI.LogoutInputModel)
- GET /{conventional} -> src/Identity.API/Quickstart/Account/AccountController.cs#IdentityServerHost.Quickstart.UI.AccountController.Logout(System.String)
- GET /{conventional} -> src/Identity.API/Quickstart/Account/ExternalController.cs#IdentityServerHost.Quickstart.UI.ExternalController.Callback
- GET /{conventional} -> src/Identity.API/Quickstart/Account/ExternalController.cs#IdentityServerHost.Quickstart.UI.ExternalController.Challenge
- POST /{conventional} -> src/Identity.API/Quickstart/Consent/ConsentController.cs#IdentityServerHost.Quickstart.UI.ConsentController.Index(IdentityServerHost.Quickstart.UI.ConsentInputModel)
8 of 17 shown
Limitations
- Identity.API's MVC controllers use conventional routing; their action paths come from route patterns configured at startup and are reported as unresolved.
- Razor and Blazor markup (
.razor,.cshtml) and XAML are not analyzed; code-behind.csfiles are. - 9% of call sites stay unresolved; the largest share (38% of them) are calls into packages that are not restored, followed by calls on expressions whose type could not be determined and by constructors with no declaration.
- Static analysis records relationships visible in the source. It does not see dynamic loading, reflection, or behaviour at runtime; verify important conclusions in the code.
Download the analysis
A full bundle of a large repository exceeds many models' context windows; the focused slices below answer one question each in a fraction of the size.
Focused slices
Every cycle group with its members and size.
scc-summary
The most depended-on and most dependent files, with the reasons they rank high.
hub-summary
Everything that depends on the main hub, two levels deep.
blast-radius
Test-side callers reachable from the most-called symbol (see limitations).
affected-tests
Detected frameworks and how their registrations were resolved.
framework-summary
Routes and handlers, with method, path and target.
framework-inventory
Resolved calls to the most-called symbol, with call sites.
call-diagnostics
Ready to run this on your own codebase?
Hosted analyses use the same analyzer as this demo, within your usage limits.