﻿
{"id":10713,"date":"2019-04-10T14:25:58","date_gmt":"2019-04-10T14:25:58","guid":{"rendered":"https:\/\/www.gencayyildiz.com\/blog\/?p=10713"},"modified":"2019-04-10T14:25:58","modified_gmt":"2019-04-10T14:25:58","slug":"asp-net-core-2-1-httpclientfactory-sinifi-ile-http-istegi-yapma","status":"publish","type":"post","link":"https:\/\/www.gencayyildiz.com\/blog\/asp-net-core-2-1-httpclientfactory-sinifi-ile-http-istegi-yapma\/","title":{"rendered":"Asp.NET Core 2.1 &#8211; HttpClientFactory S\u0131n\u0131f\u0131 \u0130le Http Iste\u011fi Yapma"},"content":{"rendered":"<div id=\"fb-root\"><\/div>\n<p>Merhaba,<\/p>\n<p>.NET Core geli\u015ftiricileri, \u00f6nceki s\u00fcr\u00fcmlerde ileri s\u00fcr\u00fclen HttpClient s\u0131n\u0131f\u0131n\u0131n t\u00fcrl\u00fc sorunlar\u0131na istinaden HttpClientFactory s\u0131n\u0131f\u0131n\u0131 geli\u015ftirmi\u015flerdir. HttpClientFactory s\u0131n\u0131f\u0131 arka planda HttpClient s\u0131n\u0131f\u0131n\u0131n bir instance&#8217;\u0131 \u00fczerinden g\u00fc\u00e7lendirilmi\u015f memory management ger\u00e7ekle\u015ftirerek \u00e7al\u0131\u015fmakta ve olas\u0131 hatalar\u0131 minimize etmektedir. Bizler bu i\u00e7eri\u011fimizde g\u00fc\u00e7lendirilmi\u015f HttpClientFactory s\u0131n\u0131f\u0131n\u0131n nas\u0131l kullan\u0131ld\u0131\u011f\u0131na dair konu\u015faca\u011f\u0131z.<\/p>\n<p><strong>Peki HttpClient s\u0131n\u0131f\u0131n\u0131n sorunlar\u0131 neydi?<\/strong><br \/>\nKompleks i\u015flemlerde birden fazla HttpClient nesnesiyle \u00e7al\u0131\u015fma ihtiyac\u0131 hissetti\u011fimiz zaman bu i\u015flem eski s\u00fcr\u00fcmlerdeki ilgili s\u0131n\u0131f ile ger\u00e7ekle\u015ftirmek olduk\u00e7a maliyetli bir hal al\u0131yordu. Her bir instance remote server i\u00e7in yeni bir connection olaca\u011f\u0131ndan dolay\u0131 birden fazla instance&#8217;\u0131n s\u00f6z konusu oldu\u011fu durumlarda uygulama i\u00e7in kullan\u0131labilecek soketlerin t\u00fcketilmesi s\u00f6z konusu olmaktayd\u0131.<\/p>\n<p>\u0130\u015fte HttpClientFactory s\u0131n\u0131f\u0131 ile birden fazla HttpClient nesnesinin do\u011fru y\u00f6netimi ger\u00e7ekle\u015ftirilmekte ve dolay\u0131s\u0131yla bahsedilen durumlardan dolay\u0131 s\u00fcre\u00e7teki olas\u0131 hatalar ortadan kald\u0131r\u0131lmaktad\u0131r.<\/p>\n<p>HttpClientFactory s\u0131n\u0131f\u0131n\u0131 kullanabilmek i\u00e7in \u00fc\u00e7 farkl\u0131 yakla\u015f\u0131m benimseyebiliriz; Bunlar<\/p>\n<ul>\n<li><em><strong>Do\u011frudan Kullanma<\/strong><\/em><\/li>\n<li><em><strong>Named Client Olu\u015fturma<\/strong><\/em><\/li>\n<li><em><strong>Typed Client Olu\u015fturma<\/strong><\/em><\/li>\n<\/ul>\n<p>\u015eimdi gelin s\u0131ras\u0131yla yukar\u0131daki yakla\u015f\u0131mlar\u0131 ele alal\u0131m;<\/p>\n<h4>HttpClientFactory S\u0131n\u0131f\u0131n\u0131n Do\u011frudan Kullan\u0131m\u0131<\/h4>\n<p>Controller contructer&#8217;\u0131 \u00fczerinden inject edilerek direkt kullanabiliriz.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class HomeController : Controller\r\n    {\r\n        private readonly IHttpClientFactory _httpClientFactory;\r\n        public HomeController(IHttpClientFactory httpClientFactory)\r\n        {\r\n            _httpClientFactory = httpClientFactory;\r\n        }\r\n\r\n        public async Task&lt;ContentResult&gt; GetHTML()\r\n        {\r\n            HttpClient _httpClient = _httpClientFactory.CreateClient();\r\n            _httpClient.BaseAddress = new Uri(&quot;https:\/\/www.gencayyildiz.com\/blog&quot;);\r\n            string result = await _httpClient.GetStringAsync(&quot;\/&quot;);\r\n            string title = result.Substring(result.IndexOf(&quot;&lt;title&gt;&quot;) + 7, result.IndexOf(&quot;&lt;\/title&gt;&quot;) - result.IndexOf(&quot;&lt;title&gt;&quot;) - 7);\r\n\r\n            return Content(title);\r\n        }\r\n    }\r\n<\/pre>\n<h4>Named Client Olu\u015fturarak Kullan\u0131m\u0131<\/h4>\n<p>Bir di\u011fer kullan\u0131m ise ilgili domaine \u00f6zel named client olu\u015fturmakt\u0131r.<\/p>\n<p>A\u015fa\u011f\u0131daki gibi belli bir adrese birden fazla istek yap\u0131ld\u0131\u011f\u0131 durumlarda HttpClient nesnesinin handikab\u0131n\u0131 ortadan kald\u0131rmakta ve daha performansl\u0131 bir \u00e7al\u0131\u015fma icra etmektedir.<br \/>\nOlmamas\u0131 gereken \u00e7al\u0131\u015fma;<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class HomeController : Controller\r\n    {\r\n        private readonly IHttpClientFactory _httpClientFactory;\r\n        public HomeController(IHttpClientFactory httpClientFactory)\r\n        {\r\n            _httpClientFactory = httpClientFactory;\r\n        }\r\n\r\n        public async Task&lt;ContentResult&gt; GetHTML()\r\n        {\r\n            HttpClient _httpClient = _httpClientFactory.CreateClient();\r\n            _httpClient.BaseAddress = new Uri(&quot;https:\/\/www.gencayyildiz.com\/blog&quot;);\r\n            string result = await _httpClient.GetStringAsync(&quot;\/&quot;);\r\n            string title = result.Substring(result.IndexOf(&quot;&lt;title&gt;&quot;) + 7, result.IndexOf(&quot;&lt;\/title&gt;&quot;) - result.IndexOf(&quot;&lt;title&gt;&quot;) - 7);\r\n\r\n\r\n            string result2 = await _httpClient.GetStringAsync(&quot;\/blog&quot;);\r\n            string description = result2.Substring(result2.IndexOf(&quot;&lt;p class=\\&quot;site-description\\&quot;&gt;&quot;) + 28, result2.IndexOf(&quot;Gen\u00e7ay Y\u0131ld\u0131z...&quot;) - result2.IndexOf(&quot;&lt;p class=\\&quot;site-description\\&quot;&gt;&quot;) - 28);\r\n\r\n            return Content((title, description).ToString());\r\n        }\r\n    }\r\n<\/pre>\n<p>Yukar\u0131daki gibi &#8220;https:\/\/www.gencayyildiz.com\/blog&#8221; adresine \u00f6zel birden fazla iste\u011fi organize edebilmek i\u00e7in a\u015fa\u011f\u0131daki gibi custom client olu\u015fturarak y\u00f6netebilir ve h\u0131z\u0131m\u0131za h\u0131z katabiliriz.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class Startup\r\n    {\r\n\r\n        .\r\n        .\r\n        .\r\n        public void ConfigureServices(IServiceCollection services)\r\n        {\r\n            .\r\n            .\r\n            .\r\n            services.AddHttpClient(&quot;gencayyildiz&quot;, c =&gt;\r\n            {\r\n                c.BaseAddress = new Uri(&quot;https:\/\/www.gencayyildiz.com\/blog&quot;);\r\n                c.DefaultRequestHeaders.Add(&quot;OzelKey&quot;, &quot;Ozel-Key&quot;);\r\n            });\r\n            .\r\n            .\r\n            .\r\n        }\r\n        .\r\n        .\r\n        .\r\n    }\r\n<\/pre>\n<p>Olmas\u0131 gereken \u00e7al\u0131\u015fma;<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class HomeController : Controller\r\n    {\r\n        private readonly IHttpClientFactory _httpClientFactory;\r\n        public HomeController(IHttpClientFactory httpClientFactory)\r\n        {\r\n            _httpClientFactory = httpClientFactory;\r\n        }\r\n\r\n        public async Task&lt;ContentResult&gt; GetHTML()\r\n        {\r\n            HttpClient _httpClient = _httpClientFactory.CreateClient(&quot;gencayyildiz&quot;);\r\n            string result = await _httpClient.GetStringAsync(&quot;\/&quot;);\r\n            string title = result.Substring(result.IndexOf(&quot;&lt;title&gt;&quot;) + 7, result.IndexOf(&quot;&lt;\/title&gt;&quot;) - result.IndexOf(&quot;&lt;title&gt;&quot;) - 7);\r\n\r\n            string result2 = await _httpClient.GetStringAsync(&quot;\/blog&quot;);\r\n            string description = result2.Substring(result2.IndexOf(&quot;&lt;p class=\\&quot;site-description\\&quot;&gt;&quot;) + 28, result2.IndexOf(&quot;Gen\u00e7ay Y\u0131ld\u0131z...&quot;) - result2.IndexOf(&quot;&lt;p class=\\&quot;site-description\\&quot;&gt;&quot;) - 28);\r\n\r\n            return Content((title, description).ToString());\r\n        }\r\n    }\r\n<\/pre>\n<h4>Typed Client Olu\u015fturarak Kullan\u0131m\u0131<\/h4>\n<p>Son kullan\u0131m tarz\u0131 ise ilgili domaine \u00f6zel custom typed client s\u0131n\u0131f\u0131 olu\u015fturmakt\u0131r.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class CustomHttpClient\r\n    {\r\n        public HttpClient Client { get; private set; }\r\n\r\n        public CustomHttpClient(HttpClient httpClient)\r\n        {\r\n            httpClient.BaseAddress = new Uri(&quot;https:\/\/www.gencayyildiz.com\/blog&quot;);\r\n            httpClient.DefaultRequestHeaders.Add(&quot;OzelKey&quot;, &quot;Ozel-Key&quot;);\r\n            Client = httpClient;\r\n        }\r\n    }\r\n<\/pre>\n<p>S\u0131n\u0131f\u0131 tasarlad\u0131ktan sonra uygulamaya dahil edilen HttpClient servisinin ilgili s\u0131n\u0131f tipinde olmas\u0131n\u0131 belirtelim.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class Startup\r\n    {\r\n\r\n        .\r\n        .\r\n        .\r\n        public void ConfigureServices(IServiceCollection services)\r\n        {\r\n            .\r\n            .\r\n            .\r\n            services.AddHttpClient&lt;CustomHttpClient&gt;();\r\n            .\r\n            .\r\n            .\r\n        }\r\n        .\r\n        .\r\n        .\r\n    }\r\n<\/pre>\n<p>Haliyle bu d\u00fczenlemeden sonra ilgili adrese istek g\u00f6nderebilmek i\u00e7in Controller&#8217;da HttpClientFactory&#8217;i de\u011fil olu\u015fturdu\u011fumuz custom typed class&#8217;\u0131 inject etmemiz yeterlidir.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class HomeController : Controller\r\n    {\r\n        private readonly CustomHttpClient _customHttpClient;\r\n        public HomeController(CustomHttpClient customHttpClient)\r\n        {\r\n            _customHttpClient = customHttpClient;\r\n        }\r\n\r\n        public async Task&lt;ContentResult&gt; GetHTML()\r\n        {\r\n            string result = await _customHttpClient.Client.GetStringAsync(&quot;\/&quot;);\r\n            string title = result.Substring(result.IndexOf(&quot;&lt;title&gt;&quot;) + 7, result.IndexOf(&quot;&lt;\/title&gt;&quot;) - result.IndexOf(&quot;&lt;title&gt;&quot;) - 7);\r\n\r\n            return Content(title);\r\n        }\r\n    }\r\n<\/pre>\n<p>Typed Client, Named Client yakla\u015f\u0131m\u0131na nazaran ayn\u0131 i\u015fi daha mimarisel bazda ve nesnel olarak ele almakt\u0131r. Lakin her ikiside ayn\u0131 adrese birden fazla istek yap\u0131laca\u011f\u0131 durumda yersiz maliyetlerden ar\u0131nd\u0131r\u0131lm\u0131\u015ft\u0131r ve olduk\u00e7a performansl\u0131d\u0131r.<\/p>\n<p>\u0130lgilenenlerin faydalanmas\u0131 dile\u011fiyle&#8230;<\/p>\n<p>Sonraki yaz\u0131lar\u0131mda g\u00f6r\u00fc\u015fmek \u00fczere&#8230;<br \/>\n\u0130yi \u00e7al\u0131\u015fmalar&#8230;<\/p>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>Merhaba, .NET Core geli\u015ftiricileri, \u00f6nceki s\u00fcr\u00fcmlerde ileri s\u00fcr\u00fclen HttpClient s\u0131n\u0131f\u0131n\u0131n t\u00fcrl\u00fc sorunlar\u0131na istinaden HttpClientFactory s\u0131n\u0131f\u0131n\u0131 geli\u015ftirmi\u015flerdir. HttpClientFactory s\u0131n\u0131f\u0131 arka planda HttpClient s\u0131n\u0131f\u0131n\u0131n bir instance&#8217;\u0131 \u00fczerinden g\u00fc\u00e7lendirilmi\u015f memory management ger\u00e7ekle\u015ftirerek \u00e7al\u0131\u015fmakta ve olas\u0131 hatalar\u0131 minimize&#46;&#46;&#46;<!-- AddThis Advanced Settings generic via filter on get_the_excerpt --><!-- AddThis Share Buttons generic via filter on get_the_excerpt --><\/p>\n","protected":false},"author":1,"featured_media":9596,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2811],"tags":[2813,2812,2814,2815],"class_list":["post-10713","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-asp-net-core-2-1","tag-asp-net-core-2-1","tag-httpclientfactory","tag-named-client","tag-typed-client"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/10713","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/comments?post=10713"}],"version-history":[{"count":13,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/10713\/revisions"}],"predecessor-version":[{"id":10726,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/10713\/revisions\/10726"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media\/9596"}],"wp:attachment":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media?parent=10713"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/categories?post=10713"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/tags?post=10713"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}