Repository navigation
Document minimal hosting and ASP.NET Core parameter binding - #204
Conversation
Fixes #175. Fixes #179. **Minimal hosting.** The page only ever showed the Startup class style, so the shape the current templates actually produce was undocumented. Minimal hosting now leads, with the Startup class kept after it since plenty of applications still use it. The rule people trip over - you cannot return an IServiceProvider from ConfigureServices and cannot add the factory to the service collection - moves up into the Quick Start, because it applies to both styles. **Parameter binding.** Since .NET 7, ASP.NET Core asks IServiceProviderIsService whether a parameter is a service to decide between injecting it and binding it from the request body. Autofac answers yes for every collection type, because collections always resolve and come back empty when nothing is registered, so a collection parameter silently stops binding from the body and starts arriving empty. Nothing throws, which is what makes it worth a warning. The fix is an explicit [FromBody], and the section explains why Autofac won't special-case empty collections rather than leaving it looking like an oversight. resolve/relationships.rst under-reported the collection types behind that: it listed IEnumerable, IList and ICollection but not IReadOnlyCollection, IReadOnlyList or arrays, which are exactly the ones reported in the issue. The heading is left alone so the anchor an upstream issue links to still resolves. **Keyed services.** The Microsoft keyed service APIs work through Autofac, so AddKeyedSingleton, [FromKeyedServices] and KeyedService.AnyKey are documented with a cross-reference to core Autofac's own keyed service support. Code fixes in the child lifetime scope sample, which could not have compiled: a variable named builder where containerBuilder was declared, constructors named Startup inside StartupOne and StartupTwo, a missing statement terminator, and stray indentation. Obsolete APIs in the retained samples: app.UseMvc() becomes routing and endpoint calls, the loggerFactory.AddConsole and AddDebug calls are gone since logging is configured on the host, and IHostingEnvironment becomes IWebHostEnvironment. Dead links: ten docs.asp.net links are gone. The nine-link "helpful links" list is now a single pointer at Microsoft's dependency injection documentation, since a list of deep links into another product's docs is what rotted in the first place. Also drops a 2016 blog post about an RC2 behavior, and the archived aspnet/DependencyInjection repository link now points into dotnet/runtime.
RST doesn't nest inline markup, so double backticks inside a bold span render as literal backtick characters rather than code. Sphinx can't warn about it - the markup is valid, just not what was meant - so the only way to catch it is to read the output. Fixes the Quick Start callout on the ASP.NET Core page, which was inconsistent with the [FromBody] callout further down the same page that already closed the bold around the literal. servicefabric.rst:115 had the identical defect and rendered wrong for the same reason. It predates this branch and isn't ASP.NET Core, but it's the same one-line fix and leaving a known-broken render in place to keep the diff tidy seemed worse. A scan of every page turns up no other instances, in either nesting direction.
The page now documents minimal hosting and the Startup class as separate styles, but the Example section pointed only at AspNetCoreExample. AspNetCoreNoStartupExample and AspNetCoreChildLifetimeScope had no link from anywhere in the documentation, so the two hosting styles this page added had no runnable counterpart a reader could find.
|
Added the example link fixup here as agreed, in The section listed only With this in, every example project in the Examples repository is linked from the page that documents it. The only two without links are Verified by simulating the merge — main with this branch's versions of its two files — and checking every |
Fixes #175. Fixes #179.
Minimal hosting (#175)
The page only ever showed the
Startupclass style, so the shape the current templates actually produce was undocumented — which is what #175 asked for. Minimal hosting now leads;Startupis kept after it, since plenty of applications still use it.The rule people trip over — you cannot return an
IServiceProviderfromConfigureServices, and cannot add the factory to the service collection — moved up into the Quick Start, because it applies to both styles and was previously buried in one of them.Parameter binding (#179)
This is the one worth reading. Since .NET 7, ASP.NET Core asks
IServiceProviderIsServicewhether a parameter is a service, to decide between injecting it and binding it from the request body. Autofac answers yes for every collection type, because collections always resolve and simply come back empty when nothing is registered.So a collection parameter silently stops binding from the body and starts arriving empty:
Nothing throws, which is exactly why it earns a warning directive. The fix is an explicit
[FromBody]. The section also explains why Autofac won't special-case empty collections — it would make the answer depend on registration order, break the case where you do want an empty set injected, and contradict documented collection behavior — so the guidance doesn't read like an unfixed oversight.Verified against
AutofacServiceProvider.IsService, which isComponentRegistry.IsRegistered(new TypedService(serviceType)), and the exact collection set inInternalTypeExtensions.IsGenericListOrCollectionInterfaceTypeplusCollectionRegistrationSource.That turned up a second gap.
resolve/relationships.rstlistedIEnumerable<B>,IList<B>andICollection<B>but never mentionedIReadOnlyCollection<B>,IReadOnlyList<B>or arrays — precisely the types reported in the issue. Since the new section points readers there, it's fixed here too. The heading is deliberately left alone: an upstreamAutofac.Extensions.DependencyInjectionissue links that exact anchor.Keyed services
AddKeyedSingleton,[FromKeyedServices]andKeyedService.AnyKeyall work through Autofac, cross-referenced to core Autofac's own keyed service support. Confirmed againstKeyedServiceTestsandFromKeyedServicesAttributeExtensions.Code that could not have compiled
The child lifetime scope sample had four defects: a variable named
builderwherecontainerBuilderwas declared, constructors namedStartupinsideStartupOneandStartupTwo, a missing statement terminator onTask.WhenAll, and stray indentation. These were the last of the four class/constructor mismatches I catalogued during the structural pass.Obsolete APIs and dead links
app.UseMvc()becomes routing/endpoint calls,loggerFactory.AddConsole/AddDebugare gone (logging is configured on the host), andIHostingEnvironmentbecomesIWebHostEnvironment.All ten
docs.asp.netlinks are gone. The nine-link "helpful links" list collapsed to a single pointer at Microsoft's DI documentation — a list of deep links into another product's docs is what rotted in the first place. Also dropped a 2016 blog post about RC2 behavior and its comment link, and the archivedaspnet/DependencyInjectionlink now points intodotnet/runtime.Coordination note
Your other session committed
feature/link-new-exampleslocally, which also touches this file'sExamplesection. I deliberately left that section untouched here so the two don't collide — that change belongs to its PR, and mine applies cleanly either way round.Verification
sphinx -b html -W --keep-going,doc8andpre-commitclean. Rendered HTML read for both new sections, and the page heading tree checked.Follow-up: nested inline markup
The other session spotted a real bug here while my files were briefly on its branch — thanks for passing it along. The Quick Start callout was:
**You cannot return an ``IServiceProvider`` from ``ConfigureServices``, ...**RST doesn't nest inline markup, so those double backticks rendered as literal backtick characters inside the bold:
sphinx -Wcan't catch this — the markup is perfectly valid, just not what was meant — which is why it survived the build being clean. Fixed by closing the bold around each literal, the same pattern the[FromBody]callout further down this page already used. It now renders as<strong>plus<code>, verified in the built HTML.I scanned every page for the whole bug class, in both nesting directions (literal-inside-bold, literal-inside-italic, bold-inside-literal). Exactly two instances existed: this one and
integration/servicefabric.rst:115, which had the identical defect and rendered wrong for the same reason.That second fix is included here even though it predates this branch and isn't ASP.NET Core. It's one line, it's the same defect, and leaving a known-broken render in place purely to keep the diff on-topic seemed like the wrong trade. Easy to split out if you'd rather.