Asp.Net Core da HttpClientFactory Kullanımı (Basic Usage)
Selamlar,
Bir önceki yazımda HttpClient kullanım hataları ve HttpClientHandler ile alakalı çıkan sıkıntılardan ve bunlara HttpClientFactory ile gelen düzeltmelerden bahsetmiştim. Bu yazımda HttpClientFactory nin bir asp.net core projesinde farklı kullanım şekillerini göreceğiz.
HttpClientFactory yi bir Asp.Net Core projenizde kullanabilmenizin 4 farklı yöntemi mevcut
Bunlar;
- Basic Usage
- Named Clients
- Typed Clients
- Generated Clients
Bunlardan ilki ile incelemeye başlayalım.
Haberleşeceğimiz url yine randomuser/me olsun.
Öncelikle Asp.Net Core Projemizdeki Startup dosyasında service lerimiz konfigüre ettiğimiz ConfigureServices metodu içerisine AddHttpClient diyerek, proje içerisinde HttpClientFactory kullanacağımızı söylemiş oluyoruz.
public void ConfigureServices(IServiceCollection services)
{
services.Configure(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
//Basic Implementation
services.AddHttpClient();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
Bu işlemden sonra artık HttpClientFactory en basic hali ile kullanımımıza hazır hale geliyor.
Peki bir asp.net core projemiz deki bir controller içerisine gidelim ve orada bu HttpClientFactory yi nasıl kullanacağımıza bakalım.
public class HomeController : Controller { private readonly IHttpClientFactory _httpClientFactory; public HomeController(IHttpClientFactory httpClientFactory) { _httpClientFactory = httpClientFactory; } public async Task Index() { var client = _httpClientFactory.CreateClient(); var result = await client.GetAsync("https://randomuser.me/api?results=5"); ViewBag.statusCode = result.StatusCode; return View(); } ....
Yukarı daki kod bloğunda gördüğümüz gibi en temel şekilde Basic Usage kullanımı olarak IHttpClientFactory sınıfını kullanabiliriz.
Asp.Net Core un kendi dependency injection paketi i, ConfigureServices metodunda AddHttpClient dediğimiz anda, biz uygulamanın herhangi bir yerinde bu sınıfı istiyoruz dediğimizde bize istediğimizi veriyor olacak.
Burada HomeController ın constructor ında IHttpClientFactory bizim için inject edilmiş oluyor. Bizde bunu yukarıdaki fieldımızda saklayıp aşağıdaki Index action ı içerisinde kullanabiliyoruz.
_httpClientFactory.CreateClient() dediğimiz her noktada aslında arkada yeni bir HttpClient instance ı oluşuyor. Bu, özellikle bir önceki yazımı okudu iseniz garip gibi gelebilir ilk başta ama aslında hatırlarsak sorun HttpClient ta değil HttpClient Handler da idi.
HttpClientFactory her CreateClient dediğimizde yeni bir HttpClient instance ı oluşturuyor fakat arka tarafta HttpClienthandler ları pool mekanizmasına soktuğu ve onların lifetime ını kendi yönettiği için normal httpclient kullanırken karşlılaştığımız sorunlarla karşılaşmıyoruz.
Xamarin.Forms ConfinstaApp Sample Bölüm 4 – SlideOverKit, Swipable Menu
Selamlar,
Bu serimizin son yazısında yine çok faydalı bir plugin den bahsetmek istiyorum. Hem bu örnek boyunca ilerlemiş olduğumuz Confinsta app i sona erdirecek hem de uygulamalarımızda bizden ekranın farklı yerlerinde farklı şekillerde açılıp kapanan menüler istendiğinde bunu kısa ve hızlı bir şekilde nasıl hallederiz buna bakacağız.
Kullanacak olduğumuz pluginimiz SlideOverKit
Yine solutionımızdaki her projeye bunu ekledikten sonrai plaform spesifik taraflarda gerekli initialize işlemini yapıyoruz.
Detaylı kullanımı için SlideOverKit in kendi github sayfasını ve örneklerini incelemenizi öneririm. Buradan ulaşabilirsiniz.
Bu plugin confinsta app boyunca Customrenderer yazmış olmamı gerekitiren tek şey. Ama aslında yazacağınız custom renderer ın örneklerden alıp copy paste yapmaktan başka neredeyse değiştirmeniz gereken peki bir kısmı kalmıyor(class isimleri hariç) 🙂
Ama arka planda neler yaptığını bilmek isterseniz benim gibi github dan inceleyebilirsiniz.
Önce bir ekranı hatırlayalım, sonra da tek tek kod taraflarına bakalım.
Resimde gördüğünüz gibi, sağ üst köşede ki hamburger buton ikonuna basıldığında ekranın yarısı kadar ene sahip ve tam boyda bir menü sayfası açıyoruz. Tıpkı instagramda olduğu gibi.
Önce sayfanın kendisine bir bakalım.
Sayfada yukarıdaki gibi bir navigation bar kullanmak eskiden custom renderer yazmak gerektirirdi. Ama yeni gelen özellikler ile sayfanın NavigationView ını istediğimiz gibi design edebiliyoruz artık xaml tarafında. Ben sağ üst köşeye bir imaj koydum ve buna bir tapgesture ekledim. Basıldığında da menü yü toggle ediyorum. Bu kadar. Xaml tarafı şu şekilde.
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="ConfinstaApp.Views.ProfileView"> <NavigationPage.TitleView> <StackLayout HorizontalOptions="FillAndExpand" Orientation="Horizontal" Padding="10,0,10,0" Spacing="10"> <Image Source="17.png" HorizontalOptions="StartAndExpand" WidthRequest="25" HeightRequest="25"></Image> <Label Text="erhanballieker" FontSize="Medium" FontAttributes="Bold" HorizontalOptions="CenterAndExpand" VerticalOptions="Center" Margin="0,0,25,0"/> <Image Source="11.png" HorizontalOptions="End" WidthRequest="25" HeightRequest="25"> <Image.GestureRecognizers> <TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"></TapGestureRecognizer> </Image.GestureRecognizers> </Image> </StackLayout> </NavigationPage.TitleView> <ContentPage.Content> <StackLayout HorizontalOptions="Center" VerticalOptions="Center"> <Label FontSize="Medium" FontAttributes="Bold" Text="erhanballieker Profile Page" HorizontalOptions="Center"></Label> </StackLayout> </ContentPage.Content> </ContentPage>
Yukarıda gördüğünüz gibi NavigationPage.TitleView içerisinde navigation design ım var. Sayfanın content ine hiçbir şey koymadım (Bir adet label ) dışında çünkü burada odaklandığımız yer sayfa içerisine eklediğimiz açılıp kapanan menü.
Sayfanın backend tarafı ise aşağıdaki gibi. Dikkat etmemiz gereken tek şey, Sayfanın ContentPage dışında bir de IMenuContainerPage interface ini implemente etmiş olması.
Bu interface den bize 3 adet property geliyor.
Bunlar;
- SlideMenu Tipinde bir SlideMenu Prop u
- Action tipinde bir ShowMenuAction prop u
- Action tipinde bir HideMenuAction prop u
bunlar dışında sayfada sadece hamburger butonun gesturetapped event i var.
Bir diğer dikkat edeceğimiz nokta ise sayfanın constructor nda bana interface den gelen SlideMenu propertysine atadığım RightSideMenuContentView.
[XamlCompilation(XamlCompilationOptions.Compile)] public partial class ProfileView : ContentPage, IMenuContainerPage { public ProfileView() { InitializeComponent (); this.SlideMenu = new RightSideMenuContentView(); } public SlideMenuView SlideMenu { get; set; } public Action ShowMenuAction { get; set; } public Action HideMenuAction { get; set; } private async void TapGestureRecognizer_Tapped(object sender, EventArgs e) { if (this.SlideMenu.IsShown) { HideMenuAction?.Invoke(); } else { ShowMenuAction?.Invoke(); } } }
RightSideMenuContentView ın xaml tarafına bir bakalım. Projemize bir adet ContentView ekleyip xaml tarafını aşağıdaki gibi düzenliyoruz.Basit bir StackLayout içerisinde bir kaç label var. Ama dikkat etmemiz gereken şey tüm sayfanın namespacinin SlideOverKit den geliyor olması.
<?xml version="1.0" encoding="utf-8" ?> <t:SlideMenuView xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:t="clr-namespace:SlideOverKit" x:Class="ConfinstaApp.Views.SlideViews.RightSideMenuContentView"> <StackLayout Padding="15,50,15,30" Spacing="20" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand"> <Label HeightRequest="30" Margin="0,0,0,80" Text="Menu" FontSize="20" XAlign="Center" TextDecorations="Underline" /> <Label HeightRequest="30" Text="Insights" FontSize="20" XAlign="Start" YAlign="Center" TextDecorations="Underline" /> <Label HeightRequest="30" Text="Your Activity" FontSize="20" XAlign="Start" YAlign="Center" TextDecorations="Underline"/> <Label HeightRequest="30" Text="Nametag" FontSize="20" XAlign="Start" YAlign="Center" TextDecorations="Underline"/> <Label HeightRequest="30" Text="Saved" FontSize="20" XAlign="Start" YAlign="Center" TextDecorations="Underline"/> <Label HeightRequest="30" Text="Discover People" FontSize="20" XAlign="Start" YAlign="Center" TextDecorations="Underline"/> <Image HeightRequest="40" Source="nature.png"></Image> <Label HeightRequest="30" Text="Settings" FontSize="20" XAlign="Start" YAlign="Center" VerticalOptions="EndAndExpand" TextDecorations="Underline"/> </StackLayout> </t:SlideMenuView>
Slide menünün backend tarafına bakalım. ContentView dan değil de SlideMenuView dan miras alıyor olmamız ilk dikkat çeken nokta. Bu miras ın bize sunduğu bir kaç property ile de nasıl görüneceğini ayarlıyoruz.
IsFullScreen true diyerek tam sayfa açılır olmasını söylüyoruz.
WidthRequest ile istediğimiz genişliği söylüyoruz.
MenuOrienations ı RightToLeft diyerek sağdan sola açılmasını belirtiyoruz.
[XamlCompilation(XamlCompilationOptions.Compile)] public partial class RightSideMenuContentView : SlideMenuView { public RightSideMenuContentView() { InitializeComponent (); this.IsFullScreen = true; this.WidthRequest = 250; this.MenuOrientations = MenuOrientation.RightToLeft; this.BackgroundColor = Color.White; this.BackgroundViewColor = Color.Transparent; } }
Daha öncede de söylediğim gibi tüm projenin içerisinde sadece bir adet custom renderer var. o da bu plugin i kullanılabilir kulmak için. iOS Custom Renderer Kısmı aşağıdaki gibi.
[assembly: ExportRenderer(typeof(ProfileView), typeof(ProfileViewRenderer))] namespace ConfinstaApp.iOS { public class ProfileViewRenderer : PageRenderer, ISlideOverKitPageRendereriOS { public Action ViewDidAppearEvent { get; set; } public Action OnElementChangedEvent { get; set; } public Action ViewDidLayoutSubviewsEvent { get; set; } public Action ViewDidDisappearEvent { get; set; } public Action<CGSize, IUIViewControllerTransitionCoordinator> ViewWillTransitionToSizeEvent { get; set; } public ProfileViewRenderer() { new SlideOverKitiOSHandler().Init(this); } protected override void OnElementChanged(VisualElementChangedEventArgs e) { base.OnElementChanged(e); OnElementChangedEvent?.Invoke(e); } public override void ViewDidLayoutSubviews() { base.ViewDidLayoutSubviews(); ViewDidLayoutSubviewsEvent?.Invoke(); } public override void ViewDidAppear(bool animated) { base.ViewDidAppear(animated); ViewDidAppearEvent?.Invoke(animated); } public override void ViewDidDisappear(bool animated) { base.ViewDidDisappear(animated); ViewDidDisappearEvent?.Invoke(animated); } public override void ViewWillTransitionToSize(CGSize toSize, IUIViewControllerTransitionCoordinator coordinator) { base.ViewWillTransitionToSize(toSize, coordinator); ViewWillTransitionToSizeEvent?.Invoke(toSize, coordinator); } } }
Custom renderer kullanmak zorunda olmanın yanında bir iyi haber ise şu. SlideOverKit sample larından aldığınız bir ios yada android rendererlarda sadece class isimlerini düzeltip başka bir customization yapmasanız bile proje çalışır hale gelecektir. Yani aslında tam da custom renderer yazıyor sayılmazsınız.
Android Custom Renderer kısmı
[assembly: ExportRenderer(typeof(ProfileView), typeof(ProfileViewRenderer))] namespace ConfinstaApp.Droid { public class ProfileViewRenderer : PageRenderer, ISlideOverKitPageRendererDroid { public Action OnElementChangedEvent { get; set; } public Action<bool, int, int, int, int> OnLayoutEvent { get; set; } public Action<int, int, int, int> OnSizeChangedEvent { get; set; } public ProfileViewRenderer (Context context) : base (context) { new SlideOverKitDroidHandler ().Init (this, context); } protected override void OnElementChanged (ElementChangedEventArgs e) { base.OnElementChanged (e); OnElementChangedEvent?.Invoke (e); } protected override void OnLayout (bool changed, int l, int t, int r, int b) { base.OnLayout (changed, l, t, r, b); OnLayoutEvent?.Invoke (changed, l, t, r, b); } protected override void OnSizeChanged (int w, int h, int oldw, int oldh) { base.OnSizeChanged (w, h, oldw, oldh); OnSizeChangedEvent?.Invoke (w, h, oldw, oldh); } } }
Evet tüm hikaye bu kadar. .NetConf 2018 de sunumunu yapmış olduğum ve yaklaşık 1 iş günümü almış olan (sadece ui olduğu için :)) bir app in, xamarin forms ile ve xamarin forms a yeni gelen özellikler ile de nasıl bir şey ortaya çıkarabildiğini gördük.
Ekranları bir hatırlayalım.
Xamarin.Forms özelinde faydalı örneklerle dolu olduğunu düşündüğüm bu Confinsta app in proje haline buradan ulaşabilirsiniz. Aynı şekilde aynı gün yapmış olduğum diğer sunum dosyaları ve projeler burada mevcut.
Bir sonraki yazımda görüşmek üzere.