Skip to content
CAI
Software that uses CAICheck a score

VincentH-Net/Orleans.Multiservice

33.4

Weak · 7 October 2026

648

lines of production code

C#

primary language

1

measurement over time

CAI band scale
CAI lens gauges

What this system is

This system is an eShop reference implementation that demonstrates a microservices architecture using Microsoft Orleans for stateful service management. It provides distinct examples for single-team and two-team development workflows, each featuring Basket and Catalog services with corresponding API endpoints. The architecture relies on Orleans grains for persistence and business logic, supported by generated contracts and minimal API endpoints for external communication.

Features

Add CatalogService Orleans grain implementation

The CatalogService now includes a new Orleans grain (CatalogGrain) that manages product data using persistent state, exposing methods to create, retrieve, update, and delete products. The service also adds global usings for Orleans runtime and catalog contracts, and a global suppression for a specific code analysis rule.

src/Example/eShopByTwoTeams/TeamB/CatalogService · medium confidence

Add CatalogService grain for product management

The CatalogService now includes a new CatalogGrain implementation that provides the core persistence and query logic for managing products. This grain handles creating, retrieving, updating, and deleting product records, serving as the backend logic for the catalog functionality.

src/Example/eShopBySingleTeam/TeamA/CatalogService · high confidence

Add eShop by Single Team example with PowerShell automation for logical services

A new example solution for the eShop by Single Team pattern is introduced, generated from Modern.CSharp.Templates 3.0.0. It includes a solution structure with Apis, Contracts, and logical service projects (e.g., BasketService, CatalogService). To simplify extending the solution, a new AddLogicalService.ps1 script is provided, which uses the mcs-orleans-multiservice template to automatically register new logical services and update endpoint registrations.

src/Example/eShopBySingleTeam/TeamA · medium confidence

Added eShop TeamA contract definitions and global usings

The eShop by Two Teams example now includes the TeamA contract definitions, specifically the BasketContract with the IBasketGrain interface and associated record types (Basket, BasketItem) marked with Orleans serialization attributes, along with a GrainFactory extension for retrieving the basket grain. Additionally, a GlobalUsings file was added to import System.Collections.Immutable globally for the contract project.

src/Example/eShopByTwoTeams/TeamA/Contracts · high confidence

Introduce CatalogContract interface and Product model for Team B

Added the CatalogContract interface and the associated Product record, defining the contract for the catalog grain. The interface exposes methods to create, retrieve, update, and delete products, while the Product record includes Id, Name, and Price fields. This change establishes the contract layer for Team B's catalog functionality.

src/Example/eShopByTwoTeams/TeamB/Contracts · high confidence

Introduce minimal API endpoints for Basket and Catalog services

The eShop example now exposes Basket and Catalog functionality via new minimal API endpoints. The Basket service provides endpoints to retrieve, update, and empty a buyer's shopping basket, while the Catalog service allows creating, retrieving, updating, and deleting products. These endpoints are registered via a shared extension method that initializes the underlying Orleans grains, and the application is configured with Swagger UI for API exploration.

src/Example/eShopBySingleTeam/TeamA/Apis · high confidence

New eShop contract definitions for Basket and Catalog grains

The eShop example now includes new contract definitions for the Basket and Catalog domains. The Basket contract introduces a \Basket\ and \BasketItem\ record types alongside an \IBasketGrain\ interface, while the Catalog contract defines a \Product\ record and an \ICatalogGrain\ interface. These changes establish the serialization and grain interfaces required for the eShop application's Orleans-based architecture.

src/Example/eShopBySingleTeam/TeamA/Contracts · high confidence

Behavioural changes

BasketService now integrates with CatalogService to validate and update product details

The BasketService has been refactored to include a new dependency on the CatalogService. The BasketGrain now resolves and calls the CatalogServiceClientGrain to fetch current product information (name and price) for items in the basket. This change ensures that basket items are synchronized with the latest catalog data, specifically updating product names and unit prices during basket updates.

src/Example/eShopBySingleTeam/TeamA/BasketService · high confidence

BasketService refactored to use generated OpenAPI client for catalog integration

The BasketService implementation has been updated to replace the previous Orleans-based catalog contract with a generated OpenAPI client (CatalogServiceClient) that communicates with the CatalogService via HTTP. This change introduces a new BasketGrain and CatalogServiceClientGrain, alongside a regenerated CatalogService.json OpenAPI specification, enabling the basket service to fetch and update product details through a standardized API contract rather than direct grain calls.

src/Example/eShopByTwoTeams/TeamA/BasketService · high confidence

Migrate TeamB API to minimal APIs and update framework versions

The TeamB API example has been updated to use .NET 10 and Orleans 10, with the codebase migrated from controller-based endpoints to minimal APIs. This includes updating the namespace from Applicita to InnoWvateDotNet, adding a new Foundation project containing global usings, extension methods for endpoint registration, and a Program.cs that configures Orleans clustering and Swagger UI. The CatalogEndpoints.cs file now uses the minimal API pattern with direct route registration, replacing the previous controller-based approach.

src/Example/eShopByTwoTeams/TeamB/Apis/Foundation · medium confidence

Team A API migrated to minimal APIs with .NET 10 and Orleans 10

The Team A API project has been updated to use minimal APIs instead of controllers, aligning with the new namespace rules and modernizing the codebase. This change includes an upgrade to .NET 10 and Orleans 10, along with a namespace rename from 'Applicita' to 'InnoWvateDotNet'. The API endpoints for basket operations are now defined using the minimal API pattern, leveraging Orleans for state management. The Swagger UI title has been updated to reflect the team name.

src/Example/eShopByTwoTeams/TeamA/Apis · medium confidence

TeamA solution updated to Modern.CSharp.Templates 3.0 with .NET 10 and Orleans 10

The TeamA example solution has been updated to use Modern.CSharp.Templates 3.0, which targets .NET 10 and Microsoft Orleans 10. The solution now includes a \BasketService\ alongside the \CatalogService\, with the \AddLogicalService.ps1\ script updated to automatically register new endpoints. The \Readme.md\ has been refreshed to reflect the new baseline, and the solution file (\eShopTeamAof2.sln\) has been regenerated to match the new template structure.

src/Example/eShopByTwoTeams/TeamA · medium confidence

TeamB solution updated to .NET 10 and Orleans 10 with new template scaffolding

The TeamB multiservice solution has been upgraded to target .NET 10 and Microsoft Orleans 10, aligning with the latest Modern.CSharp.Templates (3.0.0) scaffolding. The solution now includes a new \AddLogicalService.ps1\ script that automatically registers endpoints for new logical services, and the \Readme.md\ has been updated to reflect the new baseline and port configuration (TeamB API on localhost:5113). The solution file \eShopTeamBof2.sln\ reflects the new project structure with Apis, CatalogService, and Contracts projects.

src/Example/eShopByTwoTeams/TeamB · medium confidence

Updated global usings and code analysis suppressions for the Basket Service

The Basket Service's Foundation layer now includes explicit global using directives for Orleans runtime and the InnoWvateDotNet.EShop.Contracts.BasketContract namespace, ensuring consistent access to these types across the project. Additionally, a new GlobalSuppressions.cs file has been added to configure code analysis rules, specifically suppressing the CA2007 ConfigureAwait warning for Orleans grains, which are not relevant to the reliability rule in this context.

src/Example/eShopByTwoTeams/TeamA/BasketService/Foundation · medium confidence

Updated global usings to reference InnoWvateDotNet contracts

The Basket and Catalog services now import global usings for Orleans.Runtime and the respective InnoWvateDotNet.EShop.Contracts namespaces (BasketContract and CatalogContract), replacing previous Applicita references. Additionally, global suppression rules for CA2007 have been added to both services to acknowledge that ConfigureAwait is not relevant for Orleans grains.

src/Example/eShopBySingleTeam/TeamA/BasketService/Foundation, src/Example/eShopBySingleTeam/TeamA/CatalogService/Foundation · medium confidence

Dependencies

Upgrade eShop examples to .NET 10 and Orleans 10

The eShopBySingleTeam and eShopByTwoTeams example solutions have been updated to target .NET 10.0 and use Microsoft.Orleans packages version 10.0.1. This includes updating the target framework in all .csproj files within these example directories and upgrading related dependencies such as Microsoft.AspNetCore.OpenApi, Swashbuckle.AspNetCore, and NSwag.ApiDescription.Client to versions compatible with .NET 10.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

Score

  • CAI 42 → 33 (-9.1)
  • Rubric changed (rubric-2026.09.15 → rubric-2026.10.1) — scores are not directly comparable.

Lenses

  • Code Health 69 → 70 (+1.4)
  • Maturity 49 → 54 (+5.3)
  • Readiness 21 → 19 (-2.6)
  • Security 100 → 37 (-62.7)

Resolved (3)

  • Documentation: no installation or build instructions (README.md)
  • Documentation: no usage examples (README.md)
  • Inconsistent naming for the product identifier concept. The Product contract uses ProductName for a string property (likely the display name/title), while the internal Catalog state uses NewProductId for an integer identifier. While the types differ (string vs int), the semantic distinction between 'Name' and 'Id' is clear, but the use of NewProductId suggests a transient or generated value rather than the canonical identifier, which is confusing when compared to standard Id parameters elsewhere (e.g., DeleteProduct(int id)). However, the more direct inconsistency is between ProductName in the contract and the lack of a consistent Name vs Id distinction in the internal model if NewProductId is meant to be the ID. A clearer inconsistency is found in the parameter naming for the product entity itself.

New (22)

  • Duplicated block (13 lines × 2) (src/Example/eShopBySingleTeam/TeamA/CatalogService/CatalogGrain.cs)
  • Duplicated block (13 lines × 2) (src/Example/eShopBySingleTeam/TeamA/CatalogService/CatalogGrain.cs)
  • Duplicated block (17 lines × 2) (src/Example/eShopBySingleTeam/TeamA/Contracts/CatalogContract/CatalogContract.cs)
  • Duplicated block (21 lines × 2) (src/Example/eShopBySingleTeam/TeamA/Apis/BasketApi/BasketsEndpoints.cs)
  • Duplicated block (39 lines × 2) (src/Example/eShopBySingleTeam/TeamA/Apis/CatalogApi/CatalogEndpoints.cs)
  • Duplicated block (41 lines × 2) (src/Example/eShopBySingleTeam/TeamA/BasketService/BasketGrain.cs)
  • Duplicated block (5 lines × 2) (src/Example/eShopBySingleTeam/TeamA/CatalogService/CatalogGrain.cs)
  • Duplicated block (6 lines × 2) (src/Example/eShopBySingleTeam/TeamA/CatalogService/CatalogGrain.cs)
  • Fields named 'Product', 'Products', and 'Basket' in API endpoint classes are ambiguous. They likely hold route template strings or configuration, but the names match the domain types. This can be confused with the actual domain types or method parameters. Specifically, 'Product' and 'Products' are singular/plural forms of the same concept, but as fields, they might represent different things (e.g., a single product route vs a collection route).
  • Inconsistent naming for the dependency on the Catalog service/grain. Some fields use 'client' (e.g., CatalogServiceClientGrain.client), some use 'catalog' (e.g., CatalogEndpoints.catalog, CatalogServiceClientGrain.catalog), and one uses 'catalogServiceClient' (BasketGrain.catalogServiceClient). This creates confusion about whether the field holds a client proxy, a grain reference, or a service interface.
  • Low XML-doc coverage: BasketService (src/Example/eShopByTwoTeams/TeamA/BasketService/BasketService.csproj)
  • Low XML-doc coverage: CatalogService (src/Example/eShopByTwoTeams/TeamB/CatalogService/CatalogService.csproj)
  • Low XML-doc coverage: Contracts (src/Example/eShopByTwoTeams/TeamA/Contracts/Contracts.csproj)
  • Low XML-doc coverage: Contracts (src/Example/eShopByTwoTeams/TeamB/Contracts/Contracts.csproj)
  • Outdated: Microsoft.AspNetCore.OpenApi
  • Outdated: Microsoft.Orleans.Persistence.Memory
  • Outdated: Microsoft.Orleans.Runtime
  • Outdated: Microsoft.Orleans.Sdk
  • Outdated: NSwag.ApiDescription.Client
  • Outdated: Swashbuckle.AspNetCore
  • …and 2 more

API surface

  • Unchanged — 1 HTTP endpoints

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

VincentH-Net/Orleans.Multiservice was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 7 October 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit 6afc53c3462706a90ecd33b4775ca64d51f8d515 — the exact code this score is about.
  • Scored under rubric-2026.10.1 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-bbd7b4f07d52.