{"action":"created","issue":{"url":"https://api.github.com/repos/aspnet/HttpClientFactory/issues/110","repository_url":"https://api.github.com/repos/aspnet/HttpClientFactory","labels_url":"https://api.github.com/repos/aspnet/HttpClientFactory/issues/110/labels{/name}","comments_url":"https://api.github.com/repos/aspnet/HttpClientFactory/issues/110/comments","events_url":"https://api.github.com/repos/aspnet/HttpClientFactory/issues/110/events","html_url":"https://github.com/aspnet/HttpClientFactory/issues/110","id":322533866,"node_id":"MDU6SXNzdWUzMjI1MzM4NjY=","number":110,"title":"Support direct creation of HttpMessageHandler instances?","user":{"login":"martincostello","id":1439341,"node_id":"MDQ6VXNlcjE0MzkzNDE=","avatar_url":"https://avatars0.githubusercontent.com/u/1439341?v=4","gravatar_id":"","url":"https://api.github.com/users/martincostello","html_url":"https://github.com/martincostello","followers_url":"https://api.github.com/users/martincostello/followers","following_url":"https://api.github.com/users/martincostello/following{/other_user}","gists_url":"https://api.github.com/users/martincostello/gists{/gist_id}","starred_url":"https://api.github.com/users/martincostello/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/martincostello/subscriptions","organizations_url":"https://api.github.com/users/martincostello/orgs","repos_url":"https://api.github.com/users/martincostello/repos","events_url":"https://api.github.com/users/martincostello/events{/privacy}","received_events_url":"https://api.github.com/users/martincostello/received_events","type":"User","site_admin":false},"labels":[{"id":708938002,"node_id":"MDU6TGFiZWw3MDg5MzgwMDI=","url":"https://api.github.com/repos/aspnet/HttpClientFactory/labels/feature","name":"feature","color":"7057ff","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":{"url":"https://api.github.com/repos/aspnet/HttpClientFactory/milestones/10","html_url":"https://github.com/aspnet/HttpClientFactory/milestone/10","labels_url":"https://api.github.com/repos/aspnet/HttpClientFactory/milestones/10/labels","id":3545305,"node_id":"MDk6TWlsZXN0b25lMzU0NTMwNQ==","number":10,"title":"2.2.0-preview2","description":null,"creator":{"login":"glennc","id":234688,"node_id":"MDQ6VXNlcjIzNDY4OA==","avatar_url":"https://avatars3.githubusercontent.com/u/234688?v=4","gravatar_id":"","url":"https://api.github.com/users/glennc","html_url":"https://github.com/glennc","followers_url":"https://api.github.com/users/glennc/followers","following_url":"https://api.github.com/users/glennc/following{/other_user}","gists_url":"https://api.github.com/users/glennc/gists{/gist_id}","starred_url":"https://api.github.com/users/glennc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/glennc/subscriptions","organizations_url":"https://api.github.com/users/glennc/orgs","repos_url":"https://api.github.com/users/glennc/repos","events_url":"https://api.github.com/users/glennc/events{/privacy}","received_events_url":"https://api.github.com/users/glennc/received_events","type":"User","site_admin":false},"open_issues":2,"closed_issues":4,"state":"open","created_at":"2018-08-03T17:55:40Z","updated_at":"2018-08-15T02:43:14Z","due_on":null,"closed_at":null},"comments":22,"created_at":"2018-05-12T18:45:25Z","updated_at":"2018-08-15T16:38:13Z","closed_at":null,"author_association":"NONE","body":"_Related to IdentityServer/IdentityServer4#2311_\r\n\r\nA number of libraries provide ways to interact with their internal HTTP calls via allowing the integrator to specify an `HttpMessageHandler` implementation to use. Examples include:\r\n  1. [`RemoteAuthenticationOptions.BackchannelHttpHandler`](https://github.com/aspnet/Security/blob/f8b4f4c620e2faaeec262d302df143068c8d0b33/src/Microsoft.AspNetCore.Authentication/RemoteAuthenticationOptions.cs#L74) used by various `Microsoft.AspNetCore.Authentication.*` packages.\r\n  1. [`IdentityServerAuthenticationOptions.JwtBackChannelHandler`](https://github.com/IdentityServer/IdentityServer4.AccessTokenValidation/blob/3fd88d9ae73734504e269b08901779a7bac1484f/src/IdentityServer4.AccessTokenValidation/IdentityServerAuthenticationOptions.cs#L100) which is part of [`IdentityServer4.AccessTokenValidation`](https://github.com/IdentityServer/IdentityServer4.AccessTokenValidation).\r\n\r\nFrom looking at the [`DefaultHttpClientFactory`](https://github.com/aspnet/HttpClientFactory/blob/9edb6d12d039efdda6a8038227b146bfd12f7ab5/src/Microsoft.Extensions.Http/DefaultHttpClientFactory.cs#L117-L118) implementation, it seems like there's currently no way to be able to create an `HttpMessageHandler` directly while retaining the named-configuration, cycling, logging etc. capabilities/behaviours gained when using `IHttpClientFactory` to create `HttpClient` instances.\r\n\r\nAs a very rough pseudo-implementation, I think what would allow easy interop for application developers to leverage the HttpClientFactory features with existing libraries would be something like this:\r\n\r\n```csharp\r\npublic interface IHttpMessageHandlerFactory\r\n{\r\n    HttpMessageHandler CreateHandler(string name);\r\n}\r\n```\r\n\r\nWhich could then be implemented in `DefaultHttpClientFactory` by something like:\r\n\r\n```csharp\r\npublic HttpMessageHandler CreateHandler(string name)\r\n{\r\n    if (name == null)\r\n    {\r\n        throw new ArgumentNullException(nameof(name));\r\n    }\r\n\r\n    var entry = _activeHandlers.GetOrAdd(name, _entryFactory).Value;\r\n    var handler = new LifetimeTrackingHttpMessageHandlerWrapper(entry.Handler);\r\n\r\n    StartHandlerEntryTimer(entry);\r\n\r\n    return handler;\r\n}\r\n\r\ninternal class LifetimeTrackingHttpMessageHandlerWrapper : DelegatingHandler\r\n{\r\n    internal LifetimeTrackingHttpMessageHandler(LifetimeTrackingHttpMessageHandler innerHandler)\r\n        : base(innerHandler)\r\n    {\r\n    }\r\n\r\n    protected override void Dispose(bool disposing)\r\n    {\r\n        // Do not dispose - lifetime is tracked separately by DefaultHttpClientFactory\r\n    }\r\n}\r\n```\r\n\r\nI realise that if this is a valid use case that could be provided, it's probably far too late in the day to ship as part of 2.1."},"comment":{"url":"https://api.github.com/repos/aspnet/HttpClientFactory/issues/comments/413256444","html_url":"https://github.com/aspnet/HttpClientFactory/issues/110#issuecomment-413256444","issue_url":"https://api.github.com/repos/aspnet/HttpClientFactory/issues/110","id":413256444,"node_id":"MDEyOklzc3VlQ29tbWVudDQxMzI1NjQ0NA==","user":{"login":"martincostello","id":1439341,"node_id":"MDQ6VXNlcjE0MzkzNDE=","avatar_url":"https://avatars0.githubusercontent.com/u/1439341?v=4","gravatar_id":"","url":"https://api.github.com/users/martincostello","html_url":"https://github.com/martincostello","followers_url":"https://api.github.com/users/martincostello/followers","following_url":"https://api.github.com/users/martincostello/following{/other_user}","gists_url":"https://api.github.com/users/martincostello/gists{/gist_id}","starred_url":"https://api.github.com/users/martincostello/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/martincostello/subscriptions","organizations_url":"https://api.github.com/users/martincostello/orgs","repos_url":"https://api.github.com/users/martincostello/repos","events_url":"https://api.github.com/users/martincostello/events{/privacy}","received_events_url":"https://api.github.com/users/martincostello/received_events","type":"User","site_admin":false},"created_at":"2018-08-15T16:38:13Z","updated_at":"2018-08-15T16:38:13Z","author_association":"NONE","body":"Lifetime tracking or not aside, the problem I'm trying to solve is the ability to avoid having a hack like this in my code so I can use `HttpClientFactory` with existing code that assumes that `HttpMessageHandler` is the level of abstraction:\r\n\r\n```csharp\r\nvar factory = serviceProvider.GetRequiredService<IHttpClientFactory>();\r\nHttpClient client = factory.CreateClient(\"MyClient\");\r\n\r\nFieldInfo field = typeof(HttpMessageInvoker).GetField(\r\n    \"_handler\",\r\n    BindingFlags.GetField | BindingFlags.Instance | BindingFlags.NonPublic);\r\n\r\noptions.JwtBackChannelHandler = field.GetValue(client) as HttpMessageHandler;\r\n```"}}
{"actor":{"display_login":"martincostello"}}