Repository navigation
Description
Category
Other - .NET HTTP infrastructure and developer-experience alignment.
Problem
.NET integrations currently offer several different HTTP customization and ownership models: a direct HttpClient parameter, an init-only client property, internally constructed clients, and named/typed clients obtained through IHttpClientFactory.
Applications using multiple integrations consequently have to learn different registration, configuration, client-lifetime, and disposal conventions. We should align the infrastructure and application experience around host-managed HTTP configuration and handler pooling, building on the factory-based approach already being introduced for declarative workflows.
This is an infrastructure-consistency and developer-experience task, not a report of a security defect. A direct HttpClient parameter is not automatically something to remove: typed clients and internal helpers can legitimately consume factory-created clients. The goal is a coherent host-facing experience and explicit ownership, not a mechanical signature rewrite.
Evidence
Inventory below is based on commit fb791b540. Source links are pinned to that revision.
Existing pull requests establishing the direction
- .NET: [BREAKING] fix(dotnet): require allowed HTTP hosts #9841:
DefaultHttpRequestHandlernow requires an application-ownedIHttpClientFactory, supports a configured client name, and no longer has direct-client, creation-callback, internally owned fallback, or handler-disposal paths. The factory-only migration is in commit050475d25. See the handler constructor and acquisition/disposal path and updated HTTP workflow sample registration. - .NET: [BREAKING] fix: scope workflow MCP clients to invocations #9722: aligns declarative
DefaultMcpToolHandleraround an application-ownedIHttpClientFactoryand separates invocation-owned protocol clients from reusable HTTP infrastructure. That handler is already covered by the existing PR and is not additional work for this issue.
Public API surfaces to assess
There are six additional public entry points across three integration areas; all accept a client directly rather than a callback that creates one.
| Area | Surface and source | Current experience to align |
|---|---|---|
| A2A | AgentCard.AsAIAgent - two overloads |
Optional HttpClient is forwarded to the external A2A SDK's client factory. Establish a consistent host-managed configuration path while respecting the SDK's transport and ownership model. |
| A2A | A2ACardResolver.GetAIAgentAsync - two overloads |
Optional HttpClient is forwarded to agent construction. Card discovery uses the resolver's separately configured client; document and align both stages rather than implying this argument configures discovery. |
| Mem0 | Mem0Provider(HttpClient, ...) |
Requires the caller to provide a client with base address and authentication already configured, then retains it through an internal Mem0Client. The other constructor callback initializes provider state; it is not an HTTP-client creation callback. |
| Declarative Foundry | AzureAgentProvider.HttpClient init-only property, client construction |
An optional client is wrapped in HttpClientPipelineTransport when the provider lazily creates its Azure SDK client. Align this with the existing SDK options and transport customization paths, including the default-client behavior. |
No additional callback-returning-HttpClient surface was found in production source outside the declarative MCP handler already covered by #9722.
Internal infrastructure and already-aligned paths
- Mem0:
Mem0Client(HttpClient)retains the client supplied byMem0Provider. Keep this internal lifetime consistent with any public-provider migration. - Purview:
PurviewClient(..., HttpClient, ...)receives its client through a privately built service provider.PurviewExtensions.CreateWrappercurrently usesAddSingleton<HttpClient>(). Assess host integration and explicit ownership of both the service provider and HTTP infrastructure rather than only changing the internal constructor. - Aspire DevUI:
AspireDashboardTraceClient.IsAvailableAsyncandGetTraceEventsAsyncaccept direct clients, but their callers already acquire and dispose named factory clients: availability check, trace retrieval. These are examples of legitimate internal direct-client parameters, not necessarily migration targets. - Foundry hosting toolbox:
FoundryToolboxServicecreates its own client, stores it inCachedToolbox, and disposes it with the cached toolbox. This is an adjacent infrastructure-alignment candidate, not an externally exposed direct-client overload. Evaluate reusable HTTP-handler infrastructure separately from MCP client/session lifetimes. This service is distinct from the declarative MCP tool handler covered by .NET: [BREAKING] fix: scope workflow MCP clients to invocations #9722.
Sample experience to keep consistent
- Mem0 sample: manually configures and passes a client. Update alongside any provider API or registration changes.
- AgentWebChat:
AgentDiscoveryClient,OpenAIResponsesAgentClient, andOpenAIChatCompletionsAgentClienttake direct clients, but all three are registered as typed factory clients. Preserve this already-aligned pattern. - Invocations sample:
InvocationsAIAgentaccepts an optional client and falls back tonew HttpClient(). Align the documented registration and ownership experience. - Resilience samples:
IdempotentServiceClient(HttpClient)and the privateServerManagerreadiness helper /LocalAgentClientownership wrapper are sample-local surfaces to assess for consistency, not additional package API commitments.
Desired Outcome
- Define and document a consistent host-facing HTTP configuration and ownership model, using named/typed
IHttpClientFactoryregistrations where appropriate. - Decide which public direct-client entry points should migrate, which should remain as deliberate SDK/typed-client integration points, and how existing callers transition.
- Clearly separate the lifetime of a request/client wrapper, a pooled HTTP message-handler pipeline, and any longer-lived SDK/protocol client.
- Apply consistent configuration guidance for base addresses, authentication handlers, timeouts, cancellation, handler rotation, and disposal without requiring each integration to invent a different application setup.
- Update affected internal wiring, samples, XML/package documentation, and the corresponding public consumer-skill guidance together.
- Record any intentional public API changes in every applicable API baseline and package-compatibility suppression, with migration guidance.
- Add focused lifetime/configuration tests for behavior that changes and run the relevant builds, tests, and formatting checks.
- Retain already-factory-backed internal/typed-client patterns when they satisfy the agreed model; do not replace every
HttpClientparameter indiscriminately.
Scope is .NET only. Do not duplicate the DefaultHttpRequestHandler work in #9841 or the declarative DefaultMcpToolHandler work in #9722. Changes to third-party SDK APIs, destination-authorization behavior, or MCP protocol/session semantics are not goals of this alignment task.
Language
.NET
Acknowledgements
- I searched existing issues and did not find a duplicate.
- I will wait for explicit maintainer agreement before starting implementation of a non-trivial change.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsDone
Activity
baywet commentedon Nov 4, 2026
AzureAgentProvider -> this is duplicating a configuration path as the user can provide the http client on the options directly, we should remove that path all together to avoid a forked API surface. Also, we should think about renaming it to FoundryAgentProvider by the same occasion since the service has changed named and since this package is in preview for now.
baywet commentedon Nov 4, 2026
A2A -> this eventually goes to the A2A SDK (we're not the ones making the http requests, which is owned by the linux foundation), and anybody who has a factory can get an http client. We'll leave it as is.
baywet commentedon Nov 4, 2026
mem0 -> not released yet, so the cost of changing that is low, let's align it with IHttpClientFactory
baywet commentedon Nov 4, 2026
For things that use another SDK under the hood that accepts an http client, we could either contribute upstream, and/or add overload methods in our extensions to get the factory and pass an http client.
baywet commentedon Nov 4, 2026
Purview -> it's all internal for now, but the fact that it creates its own service scope is "odd" from a developer experience perspective, we might want to consider cleaning that up in a v2.
baywet commentedon Nov 4, 2026
Aspire DevUI -> already relies an a client factory through the httpContext and the service collection