Add ASP.NET Core controller registration docs and tests#1
Conversation
Agent-Logs-Url: https://github.com/ffMathy/ServiceScan.SourceGenerator/sessions/da938bc9-00e3-4e11-8330-ee1b1dd0086b Co-authored-by: ffMathy <2824010+ffMathy@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds documentation and verifies via tests that the existing GenerateServiceRegistrations options (AssignableTo/TypeNameFilter + AsSelf) can be used to register ASP.NET Core controller types in the DI container, including lifetime and exclusion filtering.
Changes:
- Added four new generator tests covering controller discovery/registration scenarios (
AssignableTo,TypeNameFilter, scoped lifetime, exclusions). - Added a new README section documenting controller registration patterns with
ServiceScan.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| ServiceScan.SourceGenerator.Tests/AddServicesTests.cs | Adds new tests that assert generated controller registrations for common MVC controller patterns. |
| README.md | Documents how to register controllers as DI services using existing generator options. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| ### Register ASP.NET Core controllers as services | ||
| By default, ASP.NET Core controllers are not registered in the DI container — they are instantiated using an activator. However, if you want controllers to be resolved from DI (equivalent to calling `AddControllersAsServices()`), you can register them with `ServiceScan`: | ||
| ```csharp | ||
| [GenerateServiceRegistrations( | ||
| AssignableTo = typeof(ControllerBase), |
There was a problem hiding this comment.
The README states this approach is equivalent to ASP.NET Core's IMvcBuilder.AddControllersAsServices(), but generating DI registrations alone does not switch MVC to resolve controllers from DI (it only adds the controller types to the container). To be equivalent, the docs should also instruct calling services.AddControllers().AddControllersAsServices() (or otherwise configuring ServiceBasedControllerActivator), and clarify what ServiceScan does vs what MVC needs.
| This discovers all classes inheriting from `ControllerBase` and registers each one as a transient service with its concrete type. You can then combine this with `services.AddControllers()`: | ||
| ```csharp | ||
| services.AddControllers(); | ||
| services.AddControllersAsServices(); | ||
| ``` |
There was a problem hiding this comment.
The usage snippet services.AddControllers(); services.AddControllersAsServices(); is misleading because the second call here is the generated IServiceCollection extension, not MVC's IMvcBuilder.AddControllersAsServices(). Consider updating the sample to call MVC's builder extension (e.g., services.AddControllers().AddControllersAsServices();) in addition to the generated registration method (and/or rename the generated method in the example to avoid confusion).
| } | ||
|
|
||
| [Fact] | ||
| public void AddAspNetCoreControllersWithExclusion() |
There was a problem hiding this comment.
Test name AddAspNetCoreControllersWithExclusion is inconsistent with the other controller tests (it omits AsServices). Renaming it to match the pattern would make the test suite easier to scan.
| public void AddAspNetCoreControllersWithExclusion() | |
| public void AddAspNetCoreControllersAsServicesWithExclusion() |
The existing
AssignableTo+AsSelfcapabilities already support registering controllers as DI services (equivalent toAddControllersAsServices()), but this wasn't documented or tested.Tests
AddAspNetCoreControllersAsServices— base case withAssignableTo = typeof(ControllerBase),AsSelf = trueAddAspNetCoreControllersAsServicesWithTypeNameFilter— discovery via*Controllernaming conventionAddAspNetCoreControllersAsScopedServices— non-default lifetimeAddAspNetCoreControllersWithExclusion—ExcludeByTypeNamefilteringDocumentation
New README section showing the three main patterns:
Also covers
TypeNameFilter = "*Controller"andExcludeByTypeNamevariants.No generator code changes were needed — the existing feature set handles this use case.