Are you the publisher? Claim or contact us about this channel


Embed this content in your HTML

Search

Report adult content:

click to rate:

Account: (login)

More Channels


Channel Catalog


Channel Description:

Microsoft Yazılımları

older | 1 | 2 | (Page 3)

    0 0

    Son zamanlarda UWP (Universal Windows Platform) ile ilgileniyor olmam sayesinde yeni şeyler öğrendim, bu öğrendiklerimi parça parça -eğer siz de Windows 10 uygulama geliştirme işleriyle uğraşıyorsanız- anlatmak isterim. Bunların başında bir template geliyor ve bu template aslında yapmanız gereken işlerin %80'ini sizin için yapıyor. Tamam da neden buradan başlıyoruz? Hemen konuya girelim.

    Geçmişte WPF uygulamalar yaptıysanız yani az da olsa XAML/C# biliyorsanız UWP sizin için zor olmayacaktır. Çünkü XAML ile ilgili çok fazla değişiklik yok. UWP'de olup WPF'de olmayan veya tam tersi gibi bir durum söz konusu fakat işler bizler için zorlaşmamış aksine kolaylaşmış. Compiled Binding (x:Bind) işlemlerinden event binding'e çok güzel özellikler eklenmiş ki konumuz bu değil buna ileride de değinmek istiyorum.

    Gelelim template (şablon) mevzusuna. UWP application tasarımı için Microsoft'un geliştiricilere sunduğu bazı kurallar var ve sizlerden bunlara uymanız bekleniyor. Uymadığınız takdirde en fazla mağazaya uygulamanız kabul edilmez. Kısacası araştırmam ihtiyaçlarımdan doğdu ve tasarım yapmaktan hiç hoşlanmıyorum, külfet geliyor bana. O yüzden Jerry Nixon adında Microsoft çalışanı abimiz demiş ki "Bir template olsun içerisinde Hamburger Menu'den navigation service'e, Dependency Injection'dan Messenger'a, MVVM'den behavior'lara ve White/Dark tema desteğine kadar her şey olsun ve bu template bir de open source" olsun demiş. Çok da iyi demiş.

    Tüm Windows cihaz ailesi ile uyumlu mu bilmiyorum fakat telefon/tablet ve bilgisayarlarda uygulama çok güzel görünüyor. VisualStateManager dahi eklenmiş, ekran küçüldüğü zaman siz bir şey yapmıyorsunuz, Hamburger Menu'nün görünümü kendisi değişiyor. Control görünümü ile ilgili değişiklikleri eklemeniz gerekiyor hepsi bu. Bir örnek göstereyim.

    Kısacası sizin layout ile ilgili yapmanız gereken çoğu şey yapılmış. Sürekli sadece layout yükmüş gibi bahsediyorum ama MVVM implement edilmiş, ayarlar konmuş, splash screen'i hazır, NavigationService metotları "buyrun size nasıl yardımcı olabilir" der gibi gözlerinizin içine bakıyor.

    Windows SDK Güncellendiğinde Ne Olacak?

    Windows işletim sistemi ara ara büyük güncellemeler alıyor ve SDK'lar güncelleniyor. Windows 10 yayınladığı günden bu yana 10240, 10586 ve Anniversary Edition 14393 (Yıldönümü Güncellemesi) versiyonları çıktı ve T10 da bu hıza ayak uydurabiliyor. Hatta Windows Insider (beta katılım) sayesinde yayınlanmadan önce ne gibi değişiklikler geleceği, nelerin değişmesi gerektiği gibi kritik adımları önceden tespit edip T10'u güncelliyorlar. Buna da bir örnek vereyim. Windows 14393 ile gelen UI değişikliklerinden birisi de Hamburger Menu'de seçili olan item'ın solunda "seçili olduğuna dair bir ifade beliriyor" bu da T10'da var.

    Soldaki image Windows'un ayarlar menüsü, sağdaki ise benim T10 Template kullanarak yarattığım bir application'ın menüsü.

    Gördüğünüz gibi Windows üzerinde yaşanan değişiklikler de T10 Template'e ekleniyor. Ayrıca sizi temin ederim ki güncellemenin çıkmasıyla NuGet üzerinden uygulamamı güncelledim.

    T10'u Kullanmalı mıyım? Neden?

    UWP için uygulama hazırlayacaksanız kullanmanızı öneririm. Sebepleri ise:

    1. Microsoft'un, dediğim gibi uygulamanızı hazırlarken uymanızı istediği Windows uygulamarına ait belli bir tasarım kalıbı var. Nasıl Google'ın Material Design'ı varsa aynısı Microsoft için de geçerli. Sebebi ise göze ve kullanıma uygun olması,
    2. Sizi bir çok kod yazma işinden kurtarıyor. Dediğim gibi kendi içerisinde implement edilmiş (ve eklenmeye devam edecek) servisler, metotlar var,
    3. Uygulama open source (açık kaynak) ve GitHub üzerinde talepleriniz ciddiyetle dinlenip uygulanabiliyor.

    Bu arada size 3 farklı şablon seçeneği sunuluyor. Bunlar :

    1. Blank,
    2. Hamburger,
    3. Minimal.

    Evet geldik bu şablonu nerede bulabileceğiniz konusuna. T10 hakkında kod örnekleri, yol haritası, hatalar veya geliştirmeler, Wiki gibi bilgilere GitHubüzerinden erişebilirsiniz. Eklentiyi (template) direkt indirmek istiyorsanız Visual Studio'nun eklentiler kısmından (Tools -> Extensions & Updates) aratarak veya Visual Studio Galleryüzerinden indirebilirsiniz.

    NOT : Visual Studio 2015 için geçerlidir.


    0 0
  • 07/25/17--03:38: UWP Community Toolkit
  • UWP Community Toolkit

    Hatırlarsınız eskiden Microsoft'un ASP.NET projelerinde kullanılması için hazırladığı fakat herkesin kullanırken 2 kere düşündüğü 2.sinde ise vazgeçtiği bir AJAX Toolkit'i vardı. Daha sonra AJAX Toolkit'in yerini DevExpress, Telerik vs. gibi hazır kontroller sunan 3.parti kütüphaneler almıştı. Sebebi basit; ihtiyaçtı. Şimdi size anlatacağım UWP Community Toolkit de bu duruma benzer konumda.

    UWP, Windows SDK'nın güncellenmesi ile beraber yeni özellikler kazanan bir platform fakat insanların ihtiyaçlarını karşılama konusunda yetersiz olduğu anlar da olabiliyor. Microsoft bunu görüp açık kaynak kodlu bir toolkit hazırlamış: UWP Community Toolkit. Eğer UWP için kod yazdıysanız ne dediğimi anlıyorsunuzdur. En basit örneğiyle Facebook veya Twitter mobil uygulamalarında yukarıdan aşağıya çekildiğinde veri kaynağını güncelleyen bir kontrol (PullToRefreshList) olsa da (hazıra konmak evet) bunu uygulamamızda kullansak demişsinizdir. İşte UWP Community Toolkit ile mümkün.

    UWP, HoloLens'ten IoT'ye, Xbox'dan mobile kadar her platforma hitap ettiği için bir çok alanda kullanılabiliyor. Gelelim içerisinde neler olduğuna...

    Toolkit 4 bölümden oluşuyor :

    1. Kontroller (HamburgerMenu, AdaptiveGridView vs.),
    2. Servisler (Bing, Facebook, Twitter, LinkedIn vs.),
    3. Bildirimler (LiveTile, Toast vs.),
    4. Animasyonlar (Fade, Scale vs.).

    Ek olarak yardımcı metotların (HttpHelper, ImageCache vs.) da bulunduğunu söyleyeyim.

    Ben bu yazıyı yazarken versiyon 1.2 de yayınlanmış. Hazır yayınlanmışken incelemek isteyenler için kaynakların arasında onu da belirteyim.

    UWP Community Toolkit v1.1 duyurusu için buraya,

    UWP Community Toolkit v1.2 duyurusu için buraya,

    Kaynak koduna (GitHub) ulaşmak için buraya, dokümantasyona ulaşmak için buraya, örnek uygulamalara indirip denemek isterseniz de buraya tıklayabilirsiniz. UWP Community Toolkit'i kullanacaksanız demoya kesinlikle bakın. İçerisinde direkt hazır XAML kodu bile var. İşinizi kolaylaştıracaktır.

    Biraz fazla link verdim farkındayım fakat neler olup bittiğini öğrenmek istiyorsanız aradığınız her şey burada var. Son olarak, versiyon 1.3'te neler olacağını (Roadmap) görmek isterseniz de buraya tıklayabilirsiniz.

    Son olarak nasıl indiririm diyenlere => Buyrun UWP Community Toolkit Nuget paketleri

    NOT

    1. Visual Studio yüklediğinizde umarım Universal Windows App Development Tools seçeneğini seçmişsinizdir. Bu şartlardan ilki (Visual Studio kurulumu esnasında seçmediyseniz daha sonra installer üzerinden ekleme yapabiliyorsunuz),
    2. UWP uygulamarınızın çalıştırılacağı Windows 10 versiyonu minimum 10586 olmalı.

    Bol linkli yazının bonusu


    0 0
  • 07/25/17--03:38: Microsoft Connect(); // 2016
  • Connect(); //2016

    Microsoft'un 16-17 Kasım tarihlerinde düzenlediği Connect etkinliğinde hepimizi yakından ilgilendirecek gelişmeler açıklandı. Sadece Microsoft teknolojileri ile ilgili olmadığını vurgulamak istiyorum.

    Etkinlikte çok sayıda gelişmeden bahsedildi fakat ben size bazı önemli olan açıklamaları yazacağım. Merak ediyorsanız tüm gelişmelere buradan ulaşabilirsiniz, 120'den fazla oturum var.

    Mac için Visual Studio (Preview)

    Microsoft'un açık kaynak koda yüzünü çevirmesi ile yaşanan gelişmelerin haddi hesabı yok. Linux tarafında yaşanan gelişmeler her ne kadar daha heyecanlandırıcı olsa da (benim için) Mac için de güzel gelişmeler var. Bunlardan birisi Visual Studio'nun Mac'te çalışacak olması. Her ne kadar tüm VS proje tiplerini desteklemese de native iOS, Android ve Mac geliştirme yapılabiliyor (teşekkürler Xamarin). İsmi Visual Studio olsa da aslında IDE Xamarin Studio tabanlı fakat UX Visual Studio'ya ait.

    C# ve F# desteği mevcut. IntelliSense ve refactor ise Roslyn Compiler tabanlı. Ayrıca Xamarin ve .NET Core uygulamarı, Xamarin.iOS ve Xamarin.Android'de kullanılan debug motoru burada da var.

    Daha fazla bilgi ve indirmek için buraya, etkinlik oturumunu izlemek için ise buraya tıklayabilirsiniz.

    Visual Studio 2017 (RC)

    Visual Studio 2017 yeniliklerinden bahsetmektense direkt olarak kaynak linki vereyim ve siz bakın. Çünkü Microsoft, Visual Studio 2017 için detaylı açıklamalarla ve resimlerle dolu bir sayfa hazırlamış. Buyrun, yeniliklere göz atmak veya indirmek isterseniz buraya, etkinlik oturumunu izlemek istiyorsanız buraya tıklayabilirsiniz. Ayrıca Visual Studio Team Foundation Server 2017 RTM de duyuruldu, yenilikler için buraya tıklayabilirsiniz.

    Microsoft Linux Vakfı'na Platinum Üye olarak katıldı

    Dediğim gibi, yeni bir Microsoft vizyonu hepimize iyi gelecek. Şimdiden hızlı gelişmelere şait oluyoruz. (Bu arada Platinum üyeler her sene 500.000$ bağış yapmalıymış. #HerGünGereksizBirBilgi)

    Google ve Samsung .NET Vakfı'na katıldı

    Samsung'u anlarım da Google'ın bunca zaman kötülüğünden sonra açıkçası biraz şaşırdım. Gözümde Evil Co. olarak mimlenmiş (bir diğeri de eski Microsoft), Windows Phone camiasına hiç uygulama yazmayan, yazanlara da karşı çıkan (Microsoft'un yaptığı uygulamalar kaldırılmıştı), API desteğini kısıtlayan bir şirketten bahsediyoruz. Neyse, sonuçta güzel bir hamle. Biz insanlar birlikten kuvvet doğduğunu biliyoruz ama firmalar kendi ürünlerine talebi artırmak adına bundan uzak duruyordu, yola geliyorlar. Gelecekler.

    Samsung'un açık kaynak kod işletim sistemi Tizen'i duydunuz mu bilmiyorum fakat .NET desteğini duyurdu. 50 milyondan fazla cihazda (TV, IoT, mobil, giyilebilir teknoloji vs.) var olan Tizen için taze kan, .NET kullanmak için ise başka bir sebep.

    Visual Studio için Tizen etkinliğini izlemek için buraya tıklayabilirsiniz.

    SQL Server 2016 Service Pack 1 (SP1) duyuruldu

    SQL Server 2016 SP1 ile gelen yenilik/değişiklik listesi için buraya tıklayabilirsiniz.

    Linux için SQL Server duyuruldu

    Bu duyuru var ya bu duyuru, muazzam yenilikçi bir duyuru. Artık Windows OS'yi kullanma zorunluluğunun olmadığı bir dünyada oyun baştan aşağı değişecektir. (Bir yerde okumuştum SQL Server'ın yeniden yazılması söz konusu değil, sadece çerçevesi değiştirilmiş.)

    Etkinlik oturumunu izlemek için buraya tıklayabilirsiniz.

    Bu duyuruların dışında

    • .NET Core, ASP.NET Core, Entity Framework Core 1.1,
    • Visual Studio Mobile Center Preview.

    duyuruları da yapıldı. Etkinlik ile ilgili kısa kısa notlar, haberler ve açıklamalar içeren bu sheet'e göz atmanızı öneririm.

    Ek olarak, Microsoft Türkiye Blog sayfasında duyuruları Türkçe bulabilirsiniz.


    0 0

    Windows 10

    Az biraz Windows platformu için uygulama yazıyorsanız Redstone adını duymuşsunuzdur. Redstone, Microsoft'un Windows 10 için yapılacak büyük güncellemelerine verdiği kod adı. Redstone 1, hepinizin de muhtemelen şu an kullandığı Windows 10 Anniversary Update veya diğer şekilde ifade edelim Windows 10 versiyon 1607 (10.0.14393) oluyor.

    Nisan 2017 gibi gelecek olan Redstone 2 (Windows 10 Creators Update veya Windows 10 versiyon 1703) için dün Microsoft bir etkinlik düzenledi. Gelelim bu etkinlikte biz yazılımcıları neler bekliyor, ucundan bakalım.

    Başlamadan önce; oturumları izlemek istiyorum derseniz buraya, Microsoft tarafından etkinliğe dair paylaşımı okumak istiyorum derseniz de buraya tıklayabilirsiniz.

    • Universal Windows Platform

    Microsoft'un akıllı telefon piyasasına geç girmesi ve Windows 8 sonrası işletim sistemlerinde yaşadığı uygulama ekosistemi faciası hala devam ediyor. Piyasada bırakın amiral gemisini artık telefonu bile bulunmuyor. Hatta Nokia Android işletim sistemi tabanlı telefonları duyurduğu vakit 250.000'e yakın sipariş aldığını açıkladı. Bunun sebebi Windows'un mobil pazarda tek haneli paya sahip olması. Aslında bu kadar düşük pazar payına sahip olmasının diğer bir sebebi de telefon bulunmaması. Telefon olsa satmıyor çünkü uygulama yok derken böyle bir döngüye sokuyor insanı Microsoft. Xamarin olsun, Desktop Bridge (masaüstü uygulamarını UWP'ye çevirmek) olsun Microsoft'un kan kaybı durulmuyor. ÇÜNKÜ! UWP başlı başına hala geliştiriciler için uygun bir ortam değil. Öncelikle cezbetmiyor. Cezbetmesi için güzel görünüyor olması lazım, değil mi? Günümüzde işler öyle yürümüyor mu? (Evet) Son zamanlarda tanıtılan yeni Surface ürünleri de bunun bir göstergesi. Zaten Surface ailesinden geriye sadece Surface Phone kaldı, onu da göreceğiz. O yüzden Microsoft, bu etkinliği en çok UWP ve görselliğe ayırdı (Composition & XAML). Bunun yanı sıra ekstra componentler de tanıtıldı.

    Adobe, Windows 10 ile tanıtılan Ink için ve core uygulamaları için componentler yayınlayacağını söyledi,
    Facebook, Universal Windows Platform uygulamaları için Facebook App Install Ads desteği yayınlıyor,
    Telerik, Universal Windows Platform uygulamaları için 20'den fazla kontrolü (Telerik UI for UWP) ücretsiz hale getirdi ve açık kaynak koda geçtiğini duyurdu. Kontroller hakkında bilgi almak için buraya (resmi paylaşımı için buraya), GitHub üzerinden indirmek için buraya, NuGet üzerinden indirmek içinse buraya tıklayabilirsiniz.

    Visual Studio 2017 XAML için "Edit and Continue" seçeneği ile UI'da yapılacak değişiklikler direkt olarak uygulamamıza yansıyacak. Ek olarak performans artışı ve stabilite sağlanacak. UWP için kod yazdıysanız design ekranlarının ne kadar yavaş yüklendiğini ve sık sık hata verdiğini görmüşsünüzdür. Burası biraz daha detaylı fakat kısa geçiyorum.

    Ekstra not olarak düşeyim, mağazaya uygulamayı gönderme işlemleri, "Dev Center" gibi konularda da yenilikler mevcut.

    NOTLAR

    1. Visual Studio 2017, Mart'ın 7'sinde yayınlanıyor (RTM) daha fazla bilgi için buraya tıklayabilirsiniz,
    2. Microsoft, tüm dokümanlarını yeni site altında toplama işlemine kaldığı yerden devam ediyor. UWP de eklendi. Buradan inceleyebilirsiniz,
    3. Universal Windows Platform için yol haritası (roadmap) ve Windows platformu için bug takip listesi yayınladı. Buradan inceleyebilirsiniz (iki kısma da aynı sayfadan erişilebiliyor),
    4. Son zamanlarda Project Neon adı altında Windows'un yenilenmiş ve şeffaflandırılmış arayüz görselleri paylaşılıyordu. Etkinlikte göstere göstere gözümüze soktular. Bu da sanırım 2017 sonlarına doğru yayınlanacak olan Redstone 3 güncellemesi ile yayınlanacak. Aşağıda henüz konsept olan görseli inceleyebilirsiniz.
      Project Neon
    • Windows SDK for Google Analytics

    Universal Windows Platform (UWP) uygulamaları, .NET Windows uygulamaları ve Xamarin uygulamaları tarafından kullanılabilecek bu SDK (Google Universal Analytics) ile kullanıcılar gerçek zamanlı verilere ulaşabilecek. Windows Developer blogunda yayınlanan paylaşıma buradan, Github üzerinden SDK'ya erişmek için buraya tıklayabilirsiniz.

    BONUS

    • Önceki yazımda Samsung'un işletim sistemi Tizen için .NET uygulamaları yazılabileceğini ve ilk önizleme versiyonunu yayınladığını açıklamıştım. Önizleme versiyonunun ikincisi de geçen günlerde yayınlandı. İncelemek isterseniz buraya tıklayın,
    • Windows 10 Anniversary Update ile yayınlanan Project Rome için SDK yayınlandı. GitHubüzerinden erişebilirsiniz.

    0 0
  • 07/25/17--03:38: Hangfire Hakkında
  • Bugünün konusu olarak belki duyduğunuz, belki de çoktan büyük ölçekli uygulamalarınızda kullandığınız Hangfire kütüphanesinden bahsedeceğim. Hadi başlayalım. (Github)

    Hangfire Nedir?

    Background job'ları (arka plan işleri) yaratmanıza, yürütmenize ve yönetmenize kolaylık sağlayan açık kaynaklı kütüphanedir. Job storage olarak bir çok veritabanı (SQL Server, SQL Server + MSMQ, Redis ve daha fazlası), IoC Container ve Unit Test desteklemektedir. Listesi için Hangfire Extension sayfasına göz atabilirsiniz. Hangfire Sidekiq, Resque ve Celery uygulamalarına .NET alternatifidir. 

    Background Job Nedir?

    Bazı kodların arka planda çalışması gerekmektedir. Çünkü bir iş parçacığının ana thread'de çalışması hem doğası gereği hem de bazı ihtiyaçlar dahilinde uygun olmayabiliyor.

    Hangfire Kullanımının Artıları

    • Kullanımı kolay, bir kaç satırla tüm .NET uygulamalarınızda çalıştırabilirsiniz,
    • Yönetilebilirlik ve görünebilirlik sağlar,
    • İşler veritabanında tutulduğu için güvenilirdir. İş tamamlanmadıkça tamamlandı durumuna geçmez, kod bloğunun bitimine kadar çıkacak herhangi bir sorunda iş tekrar çalışacaktır,
    • Uygulamanızdan farklı, dağıtık şekilde kullanılabilir (Infrastructure),
    • ASP.NET uygulamalarında yaşanan sorunlara çözüm sağlar
      • Uzun süren request thread'ler,
      • Birden fazla yaratılmış background job instance'ı (aynı işin aynı zamanda yapılabiliyor olması sorunu),
      • IIS'in AppDomain ve App Pool recycle etmesi (Background job'ların yarım kalması ve tekrarlanmaması).

    Hangfire'ın Desteklediği Background Job Tipleri

    • Fire and forget : Bir kere ve hemen çalışan background job tipi
    var jobId = BackgroundJob.Enqueue(
        () => Console.WriteLine("Fire-and-forget!"));
    • Delayed : Bir kere fakat belirtilen sürenin sonunda çalışan background job tipi
    var jobId = BackgroundJob.Schedule(
        () => Console.WriteLine("Delayed!"),
        TimeSpan.FromDays(7));
    • Recurring : Çok kez ve belirtilmiş CRON sürecinde (günlük, saatlik, haftalık veya CRON expressions vb.) çalışan background job tipi
    RecurringJob.AddOrUpdate(
        () => Console.WriteLine("Recurring!"),
        Cron.Daily);
    • Continuations : Tanımlanan ana işin bitiminde çalışan background job tipi
    BackgroundJob.ContinueWith(
        jobId,
        () => Console.WriteLine("Continuation!"));
    • Batch(PRO) : Birden fazla işin grup halinde çalışan background job tipi
    var batchId = BatchJob.StartNew(x =>
    {
        x.Enqueue(() => Console.WriteLine("Job 1"));
        x.Enqueue(() => Console.WriteLine("Job 2"));
    });
    • BatchContinuations(PRO) : Grup halinde çalışan ana background job'ın bitimiyle çalışan background job tipi
    BatchJob.ContinueWith(batchId, x =>
    {
        x.Enqueue(() => Console.WriteLine("Last Job"));
    });

    NOT : PRO olarak ifade edilen background job tipleri Hangfire'ın ücretsiz sürümünde yer almamaktadır. Yıllık ücret karşılığında bu background job'lara erişilebilir. Ücretlendirme ile ilgili bilgilere ulaşmak için Hangfire Pricing ekranına göz atabilirsiniz. (Ek olarak : Compleks iş akışları, Redis depolama desteği, performance counter işlemleri)

    Hangfire Architecture

    Hangfire Kurulum ve Konfigürasyon

    Hangfire'ı kullanmak istediğiniz projenize Nuget Package Manager yoluyla veya komutla Hangfire'ı yükleyin.

    Hangfire NuGet Package

    Komut : PM> Install-Package Hangfire (Nuget)

    NOT : Farklı proje tipleri için farklı paketler yüklemeniz gerekebilir. Örneğin console uygulaması için Hangfire.Core yüklemeniz lazım fakat IIS'de host edilen web uygulaması için Owin de yüklenmelidir (dependency => Hangfire). Yükleme ve paket ile ilgili bilgiler için Hangfire Installation sayfasına göz atabilirsiniz.

    Aşağıda paylaştığım konfigürasyon örneği (en basit haliyle), ASP.NET MVC projesidir.

    using Owin;
    using Microsoft.Owin;
    using Hangfire;
    using HangfireDemo;
    
    [assembly: OwinStartup(typeof(Startup))]
    namespace HangfireDemo
    {
        public partial class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                // Hangfire sunucu bağlantı
                GlobalConfiguration.Configuration.
                    UseSqlServerStorage(@"Server=.\SQLExpress;Database=HangfireDemo;Trusted_Connection=True;");
    
                // Hangfire dashboard kullan
                app.UseHangfireDashboard();
    
                // Hangfire sunucu kullan
                app.UseHangfireServer();
            }
        }
    }

    NOT : Batch kullanmak istiyorsanız ekstradan "GlobalConfiguration.Configuration.UseBatches()" satırını eklemeniz gerekiyor.

    Hangfire yaratılan job'ları veritabanında tutar, tamamlandıkça da kendisi siler. Veritabanını kendisi yaratmıyor fakat gerekli tabloları kendisi oluşturuyor. (Uygulamanızın veritabanı ile Hangfire veritabanı farklı olabilir.)

    Uygulamayı çalıştırdığınızda tabloların oluştuğunu göreceksiniz.

    Hangfire veritabanı tabloları

    Hangfire dashboard'a ulaşmak için uygulamanızın URL'inin sonuna "/hangfire" yazmanız yeterli.

    Hangfire Dashboard

    Hangfire Entegrasyonu

    Hangfire'ı uygulamanızda kullanırken uygulayabileceğiniz bir kaç farklı senaryo var.

    • Single Process
      Hangfire Single Process
    • Web Garden
      Hangfire Web Garden
    • Web Farm
      Hangfire Web Farm
    • Separate Service
      Hangfire Separate Service
    • Separate Server
      Hangfire Separate Server

    Hangfire Parametre İşlemleri

    • Çoklu parametre desteği var,
    • Parametreler serialise (JSON) edilip veritabanında tutuluyor (Array, collection, custom object),
    • Referans parametre ve ref ve out keyword'leri için desteği bulunmamaktadır,
    • Tüm kayıt yerine Id gibi belirgin değerin tutulması tavsiye edilir. Sebebi ise job storage'da tutulacak kaydın boyutu daha küçük olması.

    Hangfire Dashboard

    Host İşlemi

    • OWIN Middleware olarak yazılmıştır
      • ASP.NET, Nancy ve ServiceStack
    • OWIN Self Host
      • Console uygulaması ve Windows Service
    • Gereklilikler
      • Microsoft.Owin.Host.SystemWeb
      • OWIN Startup class
      • app.UseHangfireDashboard() konfigürasyon kodu

    Sunduğu Özellikler

    • Servers (sunucular) : Kullanılan Hangfire sunucuları ve bilgilerini (name, workers, queues, başladığı an ve en son çalıştığı an vs.) gösterir
    • Recurring Jobs : Yaratılan recurring job bilgilerini gösterir. Bunlar : Cron, Time Zone, Job, ne zaman çalışacağı, en son ne zaman çalıştığı ve yaratıldığı tarih. Ayrıca, her ne kadar belirli bir tarih tanımlanmış olsa da Trigger özelliği ile istenilen an tetiklenebilir.
    • Retries (tekrar) : Yaratılan job'ların hata alması durumunda job'ların gösterildiği ekrandır. Kaç kere denendiği de görülebilir. Default olarak atanmış deneme (retry) sayısı 10'dur.
    • Jobs (işler)
      • Enqueued : Sırada olan işler,
      • Scheduled : İleri tarihe ayarlanmış işler,
      • Processing : Çalışan işler,
      • Succeeded : Başarılı şekilde tamamlanmış işler,
      • Failed : Başarısız olmuş işler (tanınmış atama sayısından sonra bile hata alınıyorsa iş buraya düşer),
      • Deleted : Silinmiş işler,
      • Awaiting : Sırasını bekleyen (continuations) işler.

    Hangfire Dashboard Gelişmiş Konfigürasyon Seçenekleri

    Hangfire Dashboard URL değişikliği ve geri yönlendirme opsiyonu

                // Dashboard üzerinden "back to site" button
                var options = new DashboardOptions { AppPath = VirtualPathUtility.ToAbsolute("/Home/Index") };
                // Dashboard custom URL
                app.UseHangfireDashboard("/ApplicationHangfireDashboard", options);

    Birden fazla Hangfire Dashboard (ve/veya farklı veritabanları) kullanımı

                var storage1 = new SqlServerStorage("HangfireDatabase1");
                var storage2 = new SqlServerStorage("HangfireDatabase2");
    
                app.UseHangfireDashboard("/Hangfire1", new DashboardOptions(), storage1);
                app.UseHangfireDashboard("/Hangfire2", new DashboardOptions(), storage2);
    
                // Hangfire sunucu kullan
                // app.UseHangfireServer();

    Hangfire Dashboard Güvenlik

    Hangfire Dashboard'a default; local olarak erişilebilir. Örneğin sunucuda IIS'de çalışan bir web uygulamanızın Hangfire Dashboard'una remote (uzaktan erişim) makineden erişemezsiniz. Fakat uzaktan erişim için yetki vermeniz mümkün. Bunun için (IAuthorizationFilter 2.0.0 ile silinecek) IDashboardAuthorizationFilter interface'ini kullanmanız gerekiyor.

            public void Configuration(IAppBuilder app)
            {
                GlobalConfiguration.Configuration.
                    UseSqlServerStorage(@"Server=.\SQLExpress;Database=HangfireDemo;Trusted_Connection=True;");
    
                app.UseHangfireDashboard("/hangfire", new DashboardOptions()
                {
                    Authorization = new[] { new HangfireAuthorizationFilter() }
                });
    
                // Methodları çağırma sırası önemlidir
                // Önce authentication sonra 
                // HangFireServer
                app.UseHangfireServer();
            }
    
            public class HangfireAuthorizationFilter : IDashboardAuthorizationFilter
            {
                public bool Authorize(DashboardContext context)
                {
                    if (HttpContext.Current.User.IsInRole("RoleName"))
                        return true;
    
                    return false;
                }
            }

    Daha fazla bilgi için => http://docs.hangfire.io/en/latest/configuration/using-dashboard.html#configuring-authorization

    Hangfire Exception

    Hangfire, uygulamanızda alacağınız hataları (default tekrar deneme sayısı : 10) hata detayı ile birlikte gösterir. Hata aldığınız job, retries sekmesine düşer. Retry sayısını Global ve Method seviyesinde değiştirmek mümkün. Örneğin retry sayısını 1 yaparsanız 1. denemeden sonra tekrar hata alınması durumunda job Failed sekmesine düşecektir.
    Global seviyede retry sayısını değiştirmek için aşağıdaki kodu kullanabilirsiniz.

    GlobalJobFilters.Filters.Add(new AutomaticRetryAttribute() {  Attempts = 1});

    Method seviyesinde değiştirmek isterseniz, methodunuza aşağıdaki attribute'u ekleyebilirsiniz.

    [AutomaticRetry(Attempts = 1)]

    Eğer fail olan joblarınızın manuel değil de otomatik olarak silinmesini istiyorsanız
    AutomaticRetry(OnAttemptsExceeded = AttemptsExceededAction.Delete) kodunu kullanabilirsiniz.
    Daha fazla bilgi için => http://docs.hangfire.io/en/latest/background-processing/dealing-with-exceptions.html

    HangFire Logging

    Hangfire otomatik loglama desteğine (Serilog, NLog, Log4Net, EntLib Logging, Loupe ve Elmah) sahiptir. Otomatik loglama; startup sınıfında log provider tanımlamanızın yettiği anlamına geliyor. Ayrıca custom loglama desteği (ILogProvider, ILog) de mevcuttur.
    Daha fazla bilgi için => http://docs.hangfire.io/en/latest/configuration/configuring-logging.html

    HangFire SQL Server Ayarları

                var serverOptions = new SqlServerStorageOptions
                {
                    // Hangfire'ın ne kadar süre aralıkta kontrol edeceği bilgisi
                    // Default değeri 15 saniye
                    QueuePollInterval = TimeSpan.FromSeconds(45),
                    // Veritabanında tabloların yaratılıp yaratılmayacağı bilgisi
                    // Manuel migration işlemleri için false yapılabilir
                    // Default değeri true
                    PrepareSchemaIfNecessary = false
                };
    
                GlobalConfiguration.Configuration.UseSqlServerStorage("Veritabanı", serverOptions);

    Daha fazla bilgi için => http://docs.hangfire.io/en/latest/configuration/using-sql-server.html

    NOT : Hangfire, Redis desteklemektedir. Redis'in tercih sebepleri arasında yüksek performans (in-memory) ilk sıradadır fakat Redis kullanmak için Hangfire PRO yani ücretli versiyonu kullanılması zorunludur. Daha fazla bilgi için => http://docs.hangfire.io/en/latest/configuration/using-redis.html

    Hangfire Performance Comparison

    Ve son olarak dikkat edilmesi gerekenler...

    • Job'ları kullandığınız metotlar yarıda kesilebilir ve tekrarlanabilir,
    • Methodlarda kullandığınız parametreler, kompleks olmayan (basit), küçük ve object yerine primitif tip,
    • Unit test ve IoC'ye uygun,
    • Job takibi Polling vs. Pushing (örnek : SignalR) ayrımı gözetilerek

    yazılırsa kodunuz optimize olmuş olur.


    0 0

    8 Nisan 2017 Cumartesi günü Kadir Has Üniversitesi Cibali Kampüsü'nde ve 6 Mayıs 2017 Cumartesi günü ise Bilkent Cyberpark'ta yazılım sektörünün önemli isimleri Devnot organizasyonu ile bir araya geliyor.

    Etkinliğin konuşmacılarını gösteren afişi aşağıya bırakıyorum. Etkinlik ücretsiz.

    Etkinlik sayfası için buraya, kayıt olmak içinse buraya tıklayınız.

    Devnot Summit 2017

    Developer Summit Beykent Cyberpark


    0 0

    Windows 10

    Microsoft'un Creators Update olarak adlandırdığı kod adı ise Redstone 2 olan son ve büyük Windows 10 güncellemesi hazır. Bu güncelleme ile beraber Windows 10'un versiyonu 1703 (15063.13) olarak güncellendi. Yeni güncellemenin gelmesi demek, Windows 10'a yeni özellikler, yeni build numarası, yeni emulatorlar demek. Dolayısıyla biz yazılım geliştiriciler için güzel haberler var. Haberin sonunda sizlere gerekli bilgileri ve araçları nerelerden edinebileceğinize dair bağlantı listesi vereceğim.

    Bir önceki yazımda sene sonuna kadar çıkacak 3 büyük güncellemeden birisi olduğunu, lansmanı yapıldığında biz geliştiriciler için özellikle görsel anlamda yenilikler kattığını belirtmiştim. Bunun yanı sıra Bluetooth geliştirmeleri, Desktop Bridge iyileştirmeleri, yeni paylaşma deneyimi, Project Rome, uygulama güvenliği adına Windows Hello eklentisi gibi yenilikleri de var. Liste aslında Windows 10'un yeniliklerinden daha fazla ve heyecan verici. Windows 10'u çıkış tarihinden (11 Nisan) önce indirmeniz için Windows Upgrade Assistant uygulamasını kullanmanız gerekiyor. Bir kaç gün daha beklerseniz değişen hiçbir şey olmayacak.

    Ayrıca .NET Framework 4.7 duyuruldu. (Ekstradan Developer Tools ekranları, dokümantasyon sisteminde de geliştirmeler yapıldı.)

    NOT : Visual Studio 2017'ye yeni SDK'yı ve yeni emülatörleri yüklemenin en kolay yolu Visual Studio Installer kullanıp "Individual components" sekmesinden  Windows 10 SDK (10.0.15063.0) for UWP ve Windows 10 Mobile Emulator (Creators Update) seçeneklerini eklemek.

    1. Windows Blog yenilik listesi için buraya
      https://blogs.windows.com/buildingapps/2017/04/05/windows-10-creators-update-creators-update-sdk-released/#y1MUh2RvkLAsGxud.97
    2. Windows 10 versiyon 1703 - Mart 2017 yenilik listesi için buraya
      https://docs.microsoft.com/en-us/windows/uwp/whats-new/windows-10-version-1703
    3. Windows 10 version 1703 yeni API listesi için buraya
      https://docs.microsoft.com/en-us/windows/uwp/whats-new/windows-10-version-1703-api-diff
    4. Windows 10 SDK indirmek için buraya
      https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk
    5. .NET Framework 4.7 yenilikler listesi
      https://github.com/Microsoft/dotnet/blob/master/releases/net47/README.md

    0 0

    Kriptografi Nedir? Neden ve Nerede Kullanılır?

    Kriptografi, en geniş anlamıyla bilgileri gizlemektir. Fiziksel dünyadaki bilginin elektronik dünyaya taşınması ile ortaya çıkan güvenlik endişelerini gidermek için kullanıldığında söz bize, yazılımcılara düşer. Hepimiz gündelik hayatta güvenlik önlemleri altında hayatımıza devam ediyoruz. Bilgisayarınızı açtığınızda kim olduğunuzu kanıtlamak veya alışveriş sitesinde kredi kartı ile alışveriş yapmak bunlara verilebilecek en basit örneklerdir. Her iki işlemde de belirli parametreler (kredi kartı no. veya kullanıcı adı ve parolası) belirli adreslere gönderilip kontrol edilirken şifrelenirler.

    Encryption & Decryption

    Gizleme işlemine şifreleme diğer bir adıyla da encryption, şifrelenen mesajın şifresinin kaldırılmasına (okunması) ise decryptiondenir.
    Örneğin, size bir mesaj gönderildiğini, bu mesajın şifrelendiğini ve anahtarın sadece mesajı gönderen kişide ve sizde olduğunu düşünün. Böylece mesaj vericinin elinden çıktığı andan alıcının eline ulaştığı ana kadar şifrelenmiş olacaktır. (Aynı şifreleme algoritmasının kullanıldığı bu işleme simetrik anahtar algoritması diğer adıyla symmeric encryption denir. İleride değineceğim.)

    Encryption

    Mesajın gönderilmeden önce şifrelenmesi

    Decryption

    Mesajın alıcıya ulaşmadan önce şifrenin kaldırılması

    Kriptografinin Ana Konseptleri

    • Gizlilik: Yaptığınız işin içeriğinde kullanılan parametrelerin ne olduğunun asla bilinmemesi,
    • Bütünlük: İşlemin başından sonuna kadar şifrelenmiş verinin değişime uğramadan gideceği adrese ulaşması,
    • Reddedilmeme: Şifrelemeyi gerçekleştiren kişinin doğrulama adına imzasının olması,
    • Kimlik: Gizliliğin olduğu herhangi bir ortama erişim için kanıtlanmış kimlik.

    > Rastgele Sayılarla Kriptografi

    • Şifreleme anahtarı oluşturmak için kullanılır,
    • Bazı sistemlerde cihazın sahip olduğu donanım bilgisi şifreleme işlemlerinde kullanılır. Mesela MAC ethernet adresi gibi. Donanımda bunun kullanılamadığı durumlar da söz konusu. Burada devreye yazılım tabanlı şifreleme girmeli. Bu yöntem için tamamen "rastgele" denemez,
    • Rastgelelik durumu insan etkileşimi ile oluşturulabilir,
    • Sunucu uygulamaları için uygun değildir çünkü manipülasyona açıktır. O yüzden belirli bir algoritma ya da donanıma ait bilgiler kullanılmalıdır.

    Donald. E.Knuth adlı bilgisayar bilimcinin "Subtractive Random Number Generator" çalışması temel alınmıştır. Daha fazla bilgi için => The Art of Computer Programming

                // Farklı .NET Framework versiyonlarında
                // farklı değerler üretir (aynı seed değerler
                // olsa da)
    
                // Deterministtir, öngörülebilir
    
                Random rnd = new Random(350);
    
                for (int i = 0; i < 10; i++)
                    Console.Write("{0,3}   ",rnd.Next(-10, 11));
    
                Console.Read();

    System.Random ve Sorunları

    • Microsoft, uygulamanızda tek bir System.Random sınıfı instance'ı kullanılmasını öneriyor. Bkz. Random Class,
    • System.Random thread safe değildir (tek thread kullanımına dikkat edin aksi takdirde 0 değeri dönebilir),

    Rastgele Numaraları RNGCryptoServiceProvidersınıfı ile kullanırsanız daha güvenli şifreleme işlemleri gerçekleştirirsiniz. System.Random'a göre performans açısından daha yavaştır fakat tamamen rastgeledir.

            static void Main(string[] args)
            {
                for (int i = 0; i < 10; i++)
                    // Base64 işlemi daha okunabilir hale gelmesi için uygulanıyor
                    Console.WriteLine($"Rastgele Numara {i + 1}: {Convert.ToBase64String(GenerateRandomNumber(32))}");
    
                Console.ReadLine();
            }
    
            public static byte[] GenerateRandomNumber(int length)
            {
                // 256-bit şifreleme için
                // Length = 32 (32 byte * 8 bit = 256 bit)
                using (var randomNumberGenerator = new RNGCryptoServiceProvider())
                {
                    var randomNumber = new byte[length];
                    randomNumberGenerator.GetBytes(randomNumber);
    
                    return randomNumber;
                }
            }

    RNGCryptoServiceProvider

    > Hashing Algoritmaları İle Kriptografi

    • Verilen parametreyi kolayca hash'leyip hazırlar,
    • Hash'lenmiş bir veriyi ilk haline çevirmek için kullanılamaz, tek yönlüdür,
    • Hash'lenmiş verinin, orijinal halinde yapılacak en ufak bir değişiklik, tamamen farklı bir değerin üretilmesine sebep olacaktır,
    • İki farklı parametre aynı hash değeri üretemez (parmak izi örnek verilebilir, eşi yoktur),

    .NET uygulamarında kullanılabilecek hash çeşitleri

    Hashing Algorithms

    • Hashing ile geri döndürme işlemi yapılamaz. Yani, şifreli bir mesajı tekrar orijinal parametre haline çeviremezsiniz. Encryption'da bu mümkün. Yön farkları buradan gelmektedir,
    • Orijinal parametre değişmedikçe hash işlemi yapıldıkça üretilecek değerler aynı olacaktır (tek bir karakteri bile değişse, çok farklı bir değer üretileceğini belirtmiştik),

    MD5

    • 1991 yılında MD4'un yerini almıştır,
    • 128-bit,
    • 1996 yılında ilk açık bulundu, 2004 yılında bulunan açıkların sayısı arttı. Kriptografcılar SHA gibi diğer yöntemlerin kullanılmasını öneriyor (çok nadir de olsa iki farklı veri seti aynı hash değer üretebiliyordu),
    • Yine de eski uygulamalarda kullanılmaktadır.

    SHA (Secure Hash Algorithm)

    • SHA-1, NSA (National Security Agency) tarafından geliştirildi. 160 bit uzunluktadır. Bulunan sorunlardan ötürü daha fazla gelişimi sürmedi,
    • SHA-2, SHA-256 ve SHA-512 ailelerini temsil eder. SHA-256 256-bit, SHA-512 542-bit. NSA tarafından geliştirilmiştir,
    • SHA-3, 2012 yılında non-NSA yarışması sonucu doğmuştur. SHA-2'nin sahip olduğu hash uzunluğuna sahiptir. .NET Framework tarafından desteklenmemektedir. Üçüncü parti yazılımlarla ekleme yapmak mümnkün (.NET Framework desteği olmadığı için üzerinde durmayacağım).
            // Aşağıda belirtilen kriptografi sınıfları aynı
            // Interface'i kullanmakta => HashAlgorithm
    
            public static byte[] ComputeHashSHA1(byte[] toBeHashed)
            {
                using (var sha1 = SHA1.Create())
                    return sha1.ComputeHash(toBeHashed);
            }
    
            public static byte[] ComputeHashSHA256(byte[] toBeHashed)
            {
                using (var sha256 = SHA256.Create())
                    return sha256.ComputeHash(toBeHashed);
            }
    
            public static byte[] ComputeHashSHA512(byte[] toBeHashed)
            {
                using (var sha512 = SHA512.Create())
                    return sha512.ComputeHash(toBeHashed);
            }
    
            public static byte[] ComputeHashMD5(byte[] toBeHashed)
            {
                using (var md5 = MD5.Create())
                    return md5.ComputeHash(toBeHashed);
            }

    Hashed Message Authentication Codes (HMAC)

    Diğer adı hash MAC olan yöntemle verinizin bütünlüğü yine bir anahtar aracılığıyla kontrol edilebilir. Anahtar (input) kullanılarak şifrelenmiş veriniz, aynı anahtar kullanılarak tekrar üretilecek şifre değeri ile aynı olur ve tutarlılık kontrolü yapılabilir. Temel seviyedeki hash şifreleme sistemine göre daha az etkilidir. MD5 veya SHA ailesi kullanılarak şifreleme yapılır. Bu şifreleme yöntemine karşı en çok yapılan saldırı tipi Brute Force'tur.

    HMAC

    private const int KeySize = 64;
    
    public static byte[] GenerateKey()
    {
    	using (var randomNumberGenerator = new RNGCryptoServiceProvider())
    	{
    		var randomNumber = new byte[KeySize];
    		randomNumberGenerator.GetBytes(randomNumber);
    
    		return randomNumber;
    	}
    }
    
    //HMACxx sınıfına key verilmezse tamamen rastgele değer üretir
    
    /*HMACxx sınıfına verilecek parametrenin uzunluğu olarak 64 bit
     kullanılması öneriliyor. Düşükse tamamlanır, fazlaysa kırpılır.
    */
    
    public static byte[] ComputeHMACSHA1(byte[] toBeHashed, byte[] key)
    {
    	using (var hmac = new HMACSHA1(key))
    		return hmac.ComputeHash(toBeHashed);
    }
    
    public static byte[] ComputeHMACSHA256(byte[] toBeHashed, byte[] key)
    {
    	using (var hmac = new HMACSHA256(key))
    		return hmac.ComputeHash(toBeHashed);
    }
    
    public static byte[] ComputeHMACSHA512(byte[] toBeHashed, byte[] key)
    {
    	using (var hmac = new HMACSHA512(key))
    		return hmac.ComputeHash(toBeHashed);
    }
    
    public static byte[] ComputeHMACMD5(byte[] toBeHashed, byte[] key)
    {
    	using (var hmac = new HMACMD5(key))
    		return hmac.ComputeHash(toBeHashed);
    }

    > Şifre Depolama Yöntemleri

    • Şifresiz Kayıt

    Kesinlikle uygulanmaması gereken depolama şekli. Eğer şifrelenmesi gereken veriniz şifresiz bir şekilde yolculuk ediyor ve gideceği noktada yine şifrelenmemiş bir şekilde kayıt altında tutuluyorsa, sisteminizde çok büyük güvenlik zafiyeti vardır. Sisteme erişim halinde hassas verileriniz çıplak bir şekilde sergileniyor olacak (plain text).

    Clear Text Storage

    • Encryption

    Uygulamalarımızda hassas verilerin veritabanına şifreli olarak kaydedilmesi, veritabanına erişim sonrası yaşanacak sorunları bir nebze azaltacaktır. Fakat encrypt edilen bir verinin, tekrar kullanımı için decrypt edilmesi lazım. Yani şifre oluşturulurken kullanılan anahtar sözcüğün (key) de yönetimi söz konusu. Veritabanına kaydedilmiş şifreli verinin decrypt edilememesi gerekir. Çünkü anahtar çalınırsa tüm kilitler açılır.

    Encryption

    • Hash

    Encryption'dan daha güvenilir ve kullanışlı olan hash yönteminin de kendince sorunlar var. Önce artılarına bakalım; hash işlemi geri çevrilemediği için şifrelenmeden önceki halinin ne olacağı bilinemiyor böylece sisteme sızılması durumunda veriler kötü niyetli kişiler için anlamsız oluyor. Ayrıca key kullanılmadığı, tamamen rastgele değerler üretildiği için key management gibi bir sorun da yok.

    1. Brute Force Attack: Saldıran kişi, farklı kombinasyonlarla üretilmiş hash değerini sisteminizde kaydedilmiş herhangi bir kayıtla eşleşmesi için sürekli deneyecektir. Kulağa eşleşmesi neredeyse imkansızmış gibi geldiğinin farkındayım fakat teknolojinin nimetlerinden yararlanarak milyonlarca kaydı çok kısa süre içerisinde çoktan eşleştirmiş oluyorlar (o yüzden kullanılmış, herkes tarafından bilinen 12345 gibi şifreleri kullanmayın).
    2. Rainbow Table Attack :  Farklı şifrelerin hashlenmiş hallerini üzerinde bulunduran büyük bir kaynak (key-value ve GB'larca olması mümkün) ve bu kaynaktan sisteme girilmeye çalışıldığını düşünün,
    • Salted Hashes

    Hash kullanarak yarattığınız değerlere kendi kombinasyonlarınızı da uygulayabilirsiniz. Mesela hash'lemek istediğiniz parametrenin byte dizisi ile yine kendi yarattığınız rastgele (random) sayıların byte dizisini birleştirebilir (combine) ve bu birleşimi hash'leyebilirsiniz. Böylece Brute Force ve Rainbow Table saldırılarında önceden hashlenmiş değerlerin sizinki ile uyuşması, ya da tahmin edilebilir olması zorlaşacaktır.

    Password Salt Hashing

    public static byte[] GenerateSalt()
    {
    	const int saltLength = 32;
    
    	using (var randomNumberGenerator = new RNGCryptoServiceProvider())
    	{
    		var randomNumber = new byte[saltLength];
    		randomNumberGenerator.GetBytes(randomNumber);
    
    		return randomNumber;
    	}
    }
    
    private static byte[] Combine(byte[] first, byte[] second)
    {
    	var value = new byte[first.Length + second.Length];
    
    	Buffer.BlockCopy(first, 0, value,0, first.Length);
    	Buffer.BlockCopy(second, 0, value, first.Length, second.Length);
    
    	return value;
    }
    
    private static byte[] HashPasswordWithSalt(byte[] toBeHashed, byte[] salt)
    {
    	using (var sha256 = SHA256.Create())
    	{
    		return sha256.ComputeHash(Combine(toBeHashed, salt));
    	}
    }
    • Password-Based Key Derivation Function (PBKDF2)

    Hash fonksiyonun salt ile birlikte kullanımı bile bizim için yeteri kadar güvenli bir ortam oluşturmuyor. Bunun sebebi ise her geçen gün işlemcilerin veya bilgisayarların giderek daha da hızlanması ile Brute Force ve Rainbow Table saldırılarının tehlikeli boyutlara gelmiş olması (bkz. Moore Yasası) Haliyle bize daha güvenli bir yöntem lazım. Burada devreye RSA Public Key Cryptographic Standards serisi devreye giriyor. Diğer adı Internet Engineering Task Force's RFC 2898'dır.

    PBKDF, parametreyi (şifrelenecek veri, password) alır, üstüne salt ekler daha sonra ise belirtilen sayıda algoritmanın üreteceği değeri daha da karmaşık hale getirir. Böylece saldırılara karşı daha da güvenilir, karmaşık ve denendiği halde eşleşmesi çok daha uzun süre alacak bir değer üretilecektir. (LastPass, şifrelerinizi tek bir yerde toplayan ve yönetilebirliği artıran bir uygulama. JavaScript client için 5bin, server-side için 100bin iterasyon kullanmış bkz. LastPass Password Iterations (PBKDF2))

    NOT

    1. 64bit (8byte) salt uzunluğu öneriliyor,
    2. Sisteminizi performans açısından zorlamayacak sayıda yineleme (iterasyon) işlemi yapılmalı,
    3. Moore Yasası baz alınırsa, her iki senede yineleme sayısını iki kat artıracak şekilde işlemlerinizi gerçekleştirin,
    4. Salt hiçbir yöntemde gizli olma zorunluluğu taşımaz.

    PBKDF2

    static void Main(string[] args)
    {
    	string password = "Kompleks Şifre Örneği";
    
    	HashPassword(password, 100);
    	HashPassword(password, 1000);
    	HashPassword(password, 10000);
    	HashPassword(password, 100000);
    
    	Console.Read();
    }
    
    public static byte[] GenerateSalt()
    {
    	using (var randomNumberGenerator = new RNGCryptoServiceProvider())
    	{
    		var randomNumber = new byte[32];
    		randomNumberGenerator.GetBytes(randomNumber);
    
    		return randomNumber;
    	}
    }
    
    private static void HashPassword(string passwordToHash, int iterationNumber)
    {
    	Stopwatch stopwatch = new Stopwatch();
    	stopwatch.Start();
    
    	var hashedPassword = HashPassword(Encoding.UTF8.GetBytes(passwordToHash), GenerateSalt(), iterationNumber);
    
    	stopwatch.Stop();
    
    	Console.WriteLine($"Parametre : {passwordToHash}");
    	Console.WriteLine($"Parametrenin Hash'li Hali : {Convert.ToBase64String(hashedPassword)}");
    	Console.WriteLine($"Yineleme sayısı : {iterationNumber}, geçen süre : {stopwatch.ElapsedMilliseconds} ms");
    	Console.WriteLine();
    }
    
    private static byte[] HashPassword(byte[] password, byte[] salt, int iterationNumber)
    {
    	// Rfc2898DeriveBytes sınıfı PBKD fonksiyonudur
    	using (var rfc2898 = new Rfc2898DeriveBytes(password, salt, iterationNumber))
    		return rfc2898.GetBytes(32);
    }

    Çıktısı =>

    PBKDF2 Örnek Çıktısı

    > Simetrik Şifreleme (Symmetric Encryption)

    Çift yönlü şifrelemede kısaca değindik, birazdan farklı şifreleme tekniklerine bakacağız ama yine de kısaca değinelim.

    Hızlı, güvenilir fakat yine ortada anahtar olan, anahtar ile tüm şifrelemelerin çözülebildiği bir şifreleme türü. Tüm simetrik şifreleme sınıfları SymmetricAlgorithm abstract sınıfını miras alır. Hızlı ve güvenlidir. Encrypt ve decrypt işlemlerinde aynı anahtarı kullanıyor olmasından ötürü simetrik denmektedir.

    Simetrik Şifreleme

    • Data Encryption Standard (DES)
      IBM tarafından geliştirilmiştir. 64 bitlik key vardır fakat algoritma 56 bitlik kısmını kullanır. Güvenilirliğini test etmek için açılan meydan okuma yarışmasının (DESCHALL) 96. gününde şifre kırılmıştır. (Yarışma ve yaşanan hack olayı için daha fazla bilgiyi bu kitapta bulabilirsiniz => Brute Force: Cracking the Data Encryption Standard)

      DES
      static void Main(string[] args)
      {
      	string password = "Kompleks Şifre Örneği";
      
      	var key = GenerateRandomNumber(8);
      	var iv = GenerateRandomNumber(8);
      
      	var encrypted = Encrypt(Encoding.UTF8.GetBytes(password), key, iv);
      	var decrypted = Encoding.UTF8.GetString(Decrypt(encrypted, key, iv));
      
      	Console.WriteLine($"Orijinal hali : {password}");
      	Console.WriteLine($"Şifrelenmiş hali : {Convert.ToBase64String(encrypted)}");
      	Console.WriteLine($"Şifresi çözülmüş hali : {decrypted}");
      
      	Console.Read();
      }
      
      private static byte[] GenerateRandomNumber(int length)
      {
      	using (RNGCryptoServiceProvider randomNumberGenerator = new RNGCryptoServiceProvider())
      	{
      		var randomNumber = new byte[length];
      		randomNumberGenerator.GetBytes(randomNumber);
      
      		return randomNumber;
      	}
      }
      
      private static byte[] Encrypt(byte[] dataToEncrypt, byte[] key, byte[] iv)
      {
      	using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())
      	{
      		des.Key = key;
      		des.IV = iv;
      
      		using (MemoryStream memoryStream = new MemoryStream())
      		{
      			CryptoStream cryptoStream = new CryptoStream(memoryStream, des.CreateEncryptor(), 
      										CryptoStreamMode.Write);
      
      			cryptoStream.Write(dataToEncrypt, 0, dataToEncrypt.Length);
      			cryptoStream.FlushFinalBlock();
      
      			return memoryStream.ToArray();
      		}
      	}
      }
      
      private static byte[] Decrypt(byte[] dataToDecrypt, byte[] key, byte[] iv)
      {
      	using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())
      	{
      		des.Key = key;
      		des.IV = iv;
      
      		using (MemoryStream memoryStream = new MemoryStream())
      		{
      			CryptoStream cryptoStream = new CryptoStream(memoryStream, des.CreateDecryptor(), 
      											CryptoStreamMode.Write);
      
      			cryptoStream.Write(dataToDecrypt, 0, dataToDecrypt.Length);
      			cryptoStream.FlushFinalBlock();
      
      			return memoryStream.ToArray();
      		}
      	}
      }
      DES

    • Triples DES
      DES'in güvenilirliği sorgulanmaya başladıktan sonra yeni bir şifreleme algoritmasının temelleri de atılmış oldu. DES'e göre en büyük farklılığı yine DES'i uyguluyor olması fakat üstüne farklı 2-3 anahtarın ekleniyor olması. Birinci adımda anahtar ile oluşturulan şifreye, ikinci anahtar eklenerek tekrardan şifreleniyor (2. veya 3. anahtar. Şifrelenmiş halinden orjinal haline geri döndürmek için kullandığınız anahtar sırasını tersten işlemeniz gerekiyor.)

      Triple DES
      static void Main(string[] args)
      {
      	string password = "Kompleks Şifre Örneği";
      
      	// 3 key kullanımı
      	// 24 / 8 = 3 tane 64bit anahtar
              // 32 verirseniz hata alırsınız. Maksimum : 3 anahtar
      	// UNUTMA : 56bit kullanılıyor
      	var key = GenerateRandomNumber(24);
      	var iv = GenerateRandomNumber(8);
      
      	var encrypted = Encrypt(Encoding.UTF8.GetBytes(password), key, iv);
      	var decrypted = Encoding.UTF8.GetString(Decrypt(encrypted, key, iv));
      
      	Console.WriteLine($"Orijinal hali : {password}");
      	Console.WriteLine($"Şifrelenmiş hali : {Convert.ToBase64String(encrypted)}");
      	Console.WriteLine($"Şifresi çözülmüş hali : {decrypted}");
      
      	Console.Read();
      }
      
      private static byte[] GenerateRandomNumber(int length)
      {
      	using (RNGCryptoServiceProvider randomNumberGenerator = new RNGCryptoServiceProvider())
      	{
      		var randomNumber = new byte[length];
      		randomNumberGenerator.GetBytes(randomNumber);
      
      		return randomNumber;
      	}
      }
      
      private static byte[] Encrypt(byte[] dataToEncrypt, byte[] key, byte[] iv)
      {
      	using (TripleDESCryptoServiceProvider tripleDES = new TripleDESCryptoServiceProvider())
      	{
      		tripleDES.Key = key;
      		tripleDES.IV = iv;
      
      		using (MemoryStream memoryStream = new MemoryStream())
      		{
      			CryptoStream cryptoStream = new CryptoStream(memoryStream, tripleDES.CreateEncryptor(), 
      											CryptoStreamMode.Write);
      
      			cryptoStream.Write(dataToEncrypt, 0, dataToEncrypt.Length);
      			cryptoStream.FlushFinalBlock();
      
      			return memoryStream.ToArray();
      		}
      	}
      }
      
      private static byte[] Decrypt(byte[] dataToDecrypt, byte[] key, byte[] iv)
      {
      	using (TripleDESCryptoServiceProvider tripleDES = new TripleDESCryptoServiceProvider())
      	{
      		tripleDES.Key = key;
      		tripleDES.IV = iv;
      
      		using (MemoryStream memoryStream = new MemoryStream())
      		{
      			CryptoStream cryptoStream = new CryptoStream(memoryStream, tripleDES.CreateDecryptor(), 
      										CryptoStreamMode.Write);
      
      			cryptoStream.Write(dataToDecrypt, 0, dataToDecrypt.Length);
      			cryptoStream.FlushFinalBlock();
      
      			return memoryStream.ToArray();
      		}
      	}
      }
      Triple DES

    • Advanced Encryption Standard (AES)
      DES'in yerini alması için 2001 yılında kullanılmaya başlanmıştır. DES'in aksine Feistel Network kullanmaz. 128 bit girdi, 128, 192 veya 256 bitlik anahtar (sırasıyla 10, 12,14 yineleme yapar) kullanır. AES, en çok güvenilen şifreleme yöntemlerinden birisidir. Değiştirme-Karıştırma yöntemi ile çok karmaşık bir değer üretilir. Şifrenin kırılması için gerekli süre adına şuan bulunan süper bilgisayarlar kullanılsa bile evrenin yaşından daha fazla vakit alacağı söyleniyor. (256bit = 1.1x1077 ihtimal)

      AES

      static void Main(string[] args)
      {
      	string password = "Kompleks Şifre Örneği";
      
      	var key = GenerateRandomNumber(32);
      	var iv = GenerateRandomNumber(16);
      
      	var encrypted = Encrypt(Encoding.UTF8.GetBytes(password), key, iv);
      	var decrypted = Encoding.UTF8.GetString(Decrypt(encrypted, key, iv));
      
      	Console.WriteLine($"Orijinal hali : {password}");
      	Console.WriteLine($"Şifrelenmiş hali : {Convert.ToBase64String(encrypted)}");
      	Console.WriteLine($"Şifresi çözülmüş hali : {decrypted}");
      
      	Console.Read();
      }
      
      private static byte[] GenerateRandomNumber(int length)
      {
      	using (RNGCryptoServiceProvider randomNumberGenerator = new RNGCryptoServiceProvider())
      	{
      		var randomNumber = new byte[length];
      		randomNumberGenerator.GetBytes(randomNumber);
      
      		return randomNumber;
      	}
      }
      
      private static byte[] Encrypt(byte[] dataToEncrypt, byte[] key, byte[] iv)
      {
      	using (AesCryptoServiceProvider aes = new AesCryptoServiceProvider())
      	{
      		aes.Key = key;
      		aes.IV = iv;
      
      		using (MemoryStream memoryStream = new MemoryStream())
      		{
      			CryptoStream cryptoStream = new CryptoStream(memoryStream, aes.CreateEncryptor(), 
      										CryptoStreamMode.Write);
      
      			cryptoStream.Write(dataToEncrypt, 0, dataToEncrypt.Length);
      			cryptoStream.FlushFinalBlock();
      
      			return memoryStream.ToArray();
      		}
      	}
      }
      
      private static byte[] Decrypt(byte[] dataToDecrypt, byte[] key, byte[] iv)
      {
      	using (AesCryptoServiceProvider aes = new AesCryptoServiceProvider())
      	{
      		aes.Key = key;
      		aes.IV = iv;
      
      		using (MemoryStream memoryStream = new MemoryStream())
      		{
      			CryptoStream cryptoStream = new CryptoStream(memoryStream, aes.CreateDecryptor(), 
      										CryptoStreamMode.Write);
      
      			cryptoStream.Write(dataToDecrypt, 0, dataToDecrypt.Length);
      			cryptoStream.FlushFinalBlock();
      
      			return memoryStream.ToArray();
      		}
      	}
      }
      AES

    > Asimetrik Şifreleme (Asymmetric Encryption)

    Simetrik şifrelemenin hızlı ve güvenilir olduğundan bahsetmiştik fakat anahtar yönetimi sorunu mevcut. Anahtara sahip kişinin verebileceği hasar, tüm şifreleri kırabilmesiyle başlıyor. Bunun çözümü asimetrik şifrelemede. Asimetrik şifreleme de iki çeşit anahtar var. Birisi açık (public) diğeri ise kapalı (private). Bu iki anahtar birbiri ile (matematiksel olarak) bağlantılı ve sadece private anahtarın saklanması gerekiyor. Public key herkesin erişimine açıkken, private key sadece alıcıya aittir. Public key ile encrypt, private key ile decrypt yapılıyor. Peki private key'in ele geçirilmesi ile yaşanacak sorunlar nasıl önleniyor? Şöyle; private key'e sahip olan kişi, hangi public key'e bağlı olduğunu bilmiyor çünkü anahtar değişimi yok. Simetrik şifrelemeye göre dezavantajı ise işlemin daha yavaş olması. Sebebi ise daha kompleks bir yapıda olması.

    Asimetrik Şifreleme

    • RSA (Rivest, Shamin ve Adelman)
      • İsmini, tekniğin mucitlerinden almaktadır. RSA Security LLC firmasının bir ürünüdür,
      • RSA, diğer simetrik şifrelemelerle kullanılabilir. Birazdan hibrit şifrelemede bu konuya değineceğim,
      • 1024, 2048 ve 4096 bit anahtar kullanır. Günümüz koşullarında en az 2048 bitlik anahtar kullanılması öneriliyor. 1024 bitlik anahtar zayıf görülüyor,
      • Açık ve kapalı anahtarlar asal sayı temellidir,
      • Encryption ve decryption işlemleri matematik operasyonlarından oluşuyor, yavaş olmasının sebebi de budur (modüler matematik, çarpımların ayrımı, iki asal sayının çarpımı).

        İki farklı kullanımı mevcut. İlki, XML çıktı alabileceğiniz (ToXmlString()) veya in-memory saklayabileceğiniz provider kullanmak diğeri ise Microsoft'un kendi konteyner (container) yapısını kullanmak. Böylece yaratılan key kullanıcıya bağlanabilir, kullanıcı silindiği zaman bu bilgiler de silinir. Diğer bir avantajı ise korumak istediğiniz bir uygulamayı, sistemi veya birden fazla uygulama grubunu korumak için bir kullanıcıya (örnek : admin) bunu bağlamak. NOT : Yaratılan keyler açık şekilde bilgisayarda tutulmamalı.
    private RSAParameters _publicKey;
    private RSAParameters _privateKey;
    
    private void AssignKey()
    {
    	using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(2048))
    	{
    		// Konteyner kullanımı
    		rsa.PersistKeyInCsp = false;
    		// Public için parametre false
    		_publicKey = rsa.ExportParameters(false);
    		// Private için parametre true
    		_privateKey = rsa.ExportParameters(true);
    	}
    }
    
    private byte[] EncryptData(byte[] dataToEncrypt)
    {
    	byte[] cipherBytes;
    
    	using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(2048))
    	{
    		rsa.PersistKeyInCsp = false;
    		// Encrypt için public
    		rsa.ImportParameters(_publicKey);
    
    		cipherBytes = rsa.Encrypt(dataToEncrypt, false);
    	}
    
    	return cipherBytes;
    }
    
    private byte[] DecryptData(byte[] dataToDecrypt)
    {
    	byte[] plain;
    
    	using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(2048))
    	{
    		rsa.PersistKeyInCsp = false;
    
    		rsa.ImportParameters(_privateKey);
    		// Decrypt için private
    		plain = rsa.Decrypt(dataToDecrypt, true);
    	}
    
    	return plain;
    }

                   Konteyner kod örneği =>

    const string ContainerName = "Konteyner";
    
    private void AssignKey()
    {
    	CspParameters cspParams = new CspParameters(1);
    	cspParams.KeyContainerName = ContainerName;
    	cspParams.Flags = CspProviderFlags.UseMachineKeyStore;
    	cspParams.ProviderName = "Microsoft Strong Cryptographic Provider";
    
    	var rsa = new RSACryptoServiceProvider(cspParams) { PersistKeyInCsp = true };
    }
    
    private byte[] EncryptData(byte[] dataToEncrypt)
    {
    	byte[] cipherBytes;
    
    	var cspParams = new CspParameters { KeyContainerName = ContainerName };
    
    	using (var rsa = new RSACryptoServiceProvider(2048, cspParams))
    		cipherBytes = rsa.Encrypt(dataToEncrypt, false);
    
    	return cipherBytes;
    }
    
    private byte[] DecryptData(byte[] dataToDecrypt)
    {
    	byte[] plain;
    
    	var cspParams = new CspParameters { KeyContainerName = ContainerName };
    
    	using (var rsa = new RSACryptoServiceProvider(2048, cspParams))
    		plain = rsa.Decrypt(dataToDecrypt, false);
    
    	return plain;
    }
    
    // Konteynerdaki anahtarları silme işlemi
    //private void DeleteKeyInCsp()
    //{
    //    var cspParams = new CspParameters { KeyContainerName = ContainerName };
    //    var rsa = new RSACryptoServiceProvider(cspParams) { PersistKeyInCsp = true };
    
    //    rsa.Clear();
    //}

    > Hibrid Şifreleme (Hybrid Encryption)

    • Simetrik şifrelemede anahtar paylaşımı riskli,
    • Asimetrik şifrelemede ise simetrik şifrelemeye göre anahtar paylaşımı daha güvenilir fakat işlem yavaş.

    İki şifreleme yönteminin de dahil edildiği, daha güvenilir ve iyi bir çözüm sunmak adına hibrid şifreleme yapmak mümkün. Simetrik şifreleme anahtarının asimetrik şifreleme (RSA gibi) ile şifrelenmesi. Ortaya çıkan bu unique anahtara Session Key denir. Örnek için AES + RSA kodu yazılabilir, tekrar tekrar yazmamak adına pas geçiyorum.

    > Dijital İmza (Digital Signature)

    Kriptografinin ilkeleri konusunda bahsedilen reddedilmeme ilkesi dijital imza ile alakalıdır. Dijital imza, size, yaratılan mesajın bir sahibi olduğunu ve buna güvenmeniz için gerekli sebepleri barındırdığını belirten ibaredir. Kısacası dijital imza, uygun bir private key ile bir kullanıcı tarafından yaratıldığının en belirgin ve güvenilir ifadesidir. Asimetrik şifreleme tabanlıdır.

    • Public ve private key'lerden oluşur,
    • İmzalama işlemi private key ile gerçekleşir,
    • Doğrulama işlemi public key ile gerçekleşir.

    .NET Framework'te dijital imza 3 sınıf kullanır:

    1. RSACryptoServiceProvider,
    2. RSAPKCS1SignatureFormatter,
    3. RSAPKCS1SignatureDeformatter.

    Bu sınıflar verimizin doğruluğunu ve güvenilirliğini sağlar.

    static void Main(string[] args)
    {
    	var document = Encoding.UTF8.GetBytes("Top Secret Document");
    	byte[] hashedDocument;
    
    	using (var sha256 = SHA256.Create())
    		hashedDocument = sha256.ComputeHash(document);
    
    	AssignKey();
    
    	var signature = SignData(hashedDocument);
    
    	// True olursa kodumuz sorunsuz çalışmış demektir
    	// Verify oldu = true
    	var isVerified = VerifySignature(hashedDocument, signature);
    
    	Console.Read();
    }
    
    private static RSAParameters _publicKey;
    private static RSAParameters _privateKey;
    
    private static void AssignKey()
    {
    	using (var rsa = new RSACryptoServiceProvider(2048))
    	{
    		rsa.PersistKeyInCsp = false;
    		_publicKey = rsa.ExportParameters(false);
    		_privateKey = rsa.ExportParameters(true);
    	}
    }
    
    private static byte[] SignData(byte[] hash)
    {
    	using (var rsa = new RSACryptoServiceProvider(2048))
    	{
    		rsa.PersistKeyInCsp = false;
    		rsa.ImportParameters(_privateKey);
    
    		var rsaFormatter = new RSAPKCS1SignatureFormatter(rsa);
    		rsaFormatter.SetHashAlgorithm("SHA256");
    
    		return rsaFormatter.CreateSignature(hash);
    	}
    }
    
    private static bool VerifySignature(byte[] hash, byte[] signature)
    {
    	using (var rsa = new RSACryptoServiceProvider(2048))
    	{
    		rsa.ImportParameters(_publicKey);
    
    		var rsaDeformatter = new RSAPKCS1SignatureDeformatter(rsa);
    		rsaDeformatter.SetHashAlgorithm("SHA256");
    
    		return rsaDeformatter.VerifySignature(hash, signature);
    	}
    }

    Yukarıdaki örnekte verify işlemi sırasında hashedDocument değişkenindeki byte dizisi değerinden herhangi birisini değiştirmeniz sonucun false olmasına sebep olacaktır çünkü orijinal değerden farklı olacaktır.

    NOT : Hibrid yöntemle kodunuzu genişletmeniz mümkün.

    > SecureString

    • System.String kütüphanesi güvenli bir çözüm değil,
    • System.String kütüphanesi bazı sorunlar barındırmaktadır
      • Bellekte birden fazla kopya,
      • Şifreli değil,
      • Değiştirilebilir

    Yukarıda belirtilen sorunlar bildiğimiz string veri tipinde tutulan hassas veriler için geçerli. System.String kullanımı yerine SecureString kullanımı tavsiye edilir.

    • SecureString bellekte şifreli tutulur (erişildiğinde şifresiz hale gelir),
    • GarbaceCollector bellekte gezinirken müdahale etmez, tek kopası bulunur,
    • IDisposable interface eklentisi var,
    • Pointer kullanımı mümkün (char array).

    SecureString'in varlığı hassas bilgiyi string üzerinde tutmamanız için vardır. Hassas bilgi dışında kullanmamanız tavsiye edilir. Arka yapıda DPAPI kullanır.

    Data Protection API (DPAPI)

    • DPAPI, şifreleme ile veri güvenliği sunar (şifre ve private key),
    • İşletim sistemi seviyesinde güvenlik sağlar yani başka kütüphanelere gereksinim duymaz,
    • Parola bazlı veri güvenliği sunan bir servistir. Güvenliğin sağlanması için parola gereklidir (giriş yapan kullanıcının parolası),
    • Crypt32.dll'in bir parçasıdır, tüm Windows işletim sistemlerinde bulunur,
    • DPAPI şifrelenmiş veriyi sizin için saklamaz, saklama işlemi için kendi depolama kodunuz olmalı,
    • DPAPI kullanıcının giriş bilgilerini kullanır,
    • Master Key adında güçlü bir anahtar (TripleDES ile) üretir. Bu anahtarı da üretirken kullanıcının parolasını kullanır. Bu anahtar da depolanmaz ve bir süre sonra kullanım ömrü dolar.
    static void Main(string[] args)
    {
    	var str = ToSecureString(new[] { '1', '3', '5' });
    
    	char[] charArray = CharacterData(str);
    
    	// Baştaki orijinal verilere ulaşıyoruz
    	string unsecureString = ConvertToString(str);
    
    	Console.Read();
    }
    
    private static SecureString ToSecureString(char[] str)
    {
    	var secureString = new SecureString();
    
    	Array.ForEach(str, secureString.AppendChar);
    
    	return secureString;
    }
    
    private static char[] CharacterData(SecureString secureString)
    {
    	char[] bytes;
    	var ptr = IntPtr.Zero;
    
    	try
    	{
    		ptr = Marshal.SecureStringToBSTR(secureString);
    		bytes = new char[secureString.Length];
    
    		// Unmanaged bellekten char dizisine
    		Marshal.Copy(ptr, bytes, 0, secureString.Length);
    	}
    
    	finally
    	{
    		if (ptr != IntPtr.Zero)
    			// Unmanaged bellek temizleniyor
    			Marshal.ZeroFreeBSTR(ptr);
    	}
    
    	return bytes;
    }
    
    // Hassas verinin tekrar string'e dönüştürülmesi önerilmez
    // Bellekte birden fazla kopyası olması mümkün hale gelir
    private static string ConvertToString(SecureString securePassowrd)
    {
    	var unmanagedString = IntPtr.Zero;
    
    	try
    	{
    		// Unmanaged belleğe kopyalanıyor
    		unmanagedString = Marshal.SecureStringToGlobalAllocUnicode(securePassowrd);
    
    		return Marshal.PtrToStringUni(unmanagedString);
    	}
    
    	finally
    	{
    		Marshal.ZeroFreeGlobalAllocUnicode(unmanagedString);
    	}
    }

    GÜNCELLEME
    .NET Framework 4.7 ile gelen ve bu konuyu ilgilendiren bazı değişiklikler var

    • Improved support of RSA decryption with hardware keys,
    • Opening a cryptographic key with CspParameters.ParentWindowHandle set to this.Handle will now correctly make any PIN or password prompt be modal to the current window,
    • Enabled ClickOnce signing scenarios where certificate is identified by a cryptographic provider and private key container names.

    0 0
  • 07/25/17--03:38: C# 7 - İlk Bakış
  • C# History

    Visual Studio 2017'nin yayınlanması ile birlikte C# 7.0 da aramıza katılmış oldu. VS2017 RTM'e (son/kararlı hal) geçmeden önce dil hakkında bilgileri zaten ediniyor hatta kullanıyoruz. C# 7 ile gelen yeniliklerin yaşantımızda kullanacak kıvama gelmeden hemen önceki turumuza başlayalım.

    Bahsedeceğim konular

    • Out Variables
    • Pattern Matching,
    • Tuples,
    • Local Functions,
    • Literals, Ref. Returns, Exceptions

    Out Variables

    • Önceden tanımlamada var kullanılamıyor (int.TryParse(input, out var answer)),
    • Kullanmadan önce tanımlanması gerekiyor (demo),

    Yukarıdaki sorunlara çözüm olarak Out Variables sunuldu.

    // Eski yöntem
    private static void Run()
    {
    	string name;
    	string lastName;
    
    	GetName(out name, out lastName);
    	Console.WriteLine($"{name} {lastName}");
    }
    
    // C# 7.0 ile gelen yeni yöntem
    private static void Run2()
    {
    	GetName(out string name, out string lastName);
    	Console.WriteLine($"{name} {lastName}");
    }
    
    private static void GetName(out string name, out string lastName)
    {
    	name = "Fırat";
    	lastName = "Esmer";
    }

    Pattern Matching

    Pattern'in tanımı için şöyle güzel bir yorum var:

    Syntactic elements that can test that a value has a certain "shape".

    Bir değerin belirli bir şekle sahip olduğunu test edebilen sözdizimsel öğeler.

    static void Main(string[] args)
    {
    	PrintSum(10);
    	PrintSum2("10");
    }
    
    public static void PrintSum(object o)
    {
    	if (o is null) return; //Constant Pattern
    	if (!(o is int i)) return; // Type Pattern (Int32)
    
    	int sum = 0;
    
    	for (int j = 0; j <= i; j++)
    		sum += j;
    }
    
    public static void PrintSum2(object o)
    {
    	if (o is int i || o is string s && int.TryParse(s, out i))
    	{
    		int sum = 0;
    
    		for (int j = 0; j <= i; j++)
    			sum += j;
    	}
    }

    Koşullu switch'e de bir göz atalım, burada gelen yenilik case durumunda koşul girebiliyor olmamız. Yani test edebiliyor olmamız.

    class Program
    {
    	static void Main(string[] args)
    	{
    		Employee employee = new President();
    		employee.Salary = 200000;
    		employee.Years = 10;
    		(employee as President).ManagedEmployeeNumber = 500;
    		(employee as President).StockShares = 12000;
    
    		// Switch içerisindeki sıralama önemli
    		// Manager Employee'nin altında olsaydı hata alırdık
    		// Kalıtım alan sınıf alınan sınıftan üstte olmalı
    		switch (employee)
    		{
    			case President p when (p.StockShares < 10000):
    				Console.WriteLine($"Düşük profilli yönetici hisse senedi payı : {p.StockShares}");
    				break;
    
    			case President p when (p.StockShares >= 10000):
    				Console.WriteLine($"Yüksek profilli yönetici hisse senedi payı : {p.StockShares}");
    				break;
    
    			case Manager m:
    				Console.WriteLine($"Yönetiye bağlı kişi : {m.ManagedEmployeeNumber}");
    				break;
    
    			case Employee e:
    				Console.WriteLine($"Çalışan maaşı : {e.Salary}");
    				break;
    		}
    	}
    }
    
    public class Employee
    {
    	public int Salary { get; set; }
    	public int Years { get; set; }
    }
    
    public class Manager : Employee
    {
    	public int ManagedEmployeeNumber { get; set; }
    }
    
    public class President : Manager
    {
    	public int StockShares { get; set; }
    }

    Tuples

    Metotlardan birden fazla değeri geri döndürmek istediğimizde aklımıza gelen en uygun yöntem out parametresi. Fakat out parametresinin de elimizi kolumuzu bağladığı bazı noktalar var. Mesela okunabilirliği zayıf, async metotlarla kullanılamıyor. Burada yardımımıza Tuple (System.Tuple<T>) yetişiyor. Tuple'ı başka bir Tuple'a convert edebilirsiniz. Tuple value type'dır (referans değil).

    Öncelikle Tuples'ı kullanmak için NuGet Package kullanmamız gerektiğini belirteyim. Aşağıdaki resimde gördüğünüz gibi yüklemeyi gerçekleştirin.

    System.Tuples Nuget Package

    static void Main(string[] args)
    {
    	var numbers = GetThreeNumbers();
    	// İsimlendirme işlemini biz yapmadığımız için
    	// kendisi otomatik olarak yapıyor
    	Console.WriteLine($"{numbers.Item1},{numbers.Item2},{numbers.Item3}");
    
    	var numbersWithNames = GetThreeNumbersWithNames();
    	Console.WriteLine($"{numbersWithNames.number1},{numbersWithNames.number2},{numbersWithNames.number3}");
    }
    
    public static (int, int, int) GetThreeNumbers()
    {
    	return (1, 56, 187);
    }
    
    public static (int number1, int number2, int number3) GetThreeNumbersWithNames()
    {
    	return (1, 56, 187);
    }

    Tuple ile Dictionary kullanımı

    var tupleDictionary = new Dictionary<(int, int), string>();
    tupleDictionary.Add((16, 21), "İki kardeşin yaşları");
    
    // Sonuç = İki kardeşin yaşları
    var result = tupleDictionary[(16, 21)];

    Tuple Deconstruction örneği

    static void Main(string[] args)
    {
    	(int number1, int number2, int number3) = GetThreeNumbers();
    	Console.WriteLine($"{number1},{number2},{number3}");
    
    	// Diğer kullanım şekli
    	int _number1;
    	int _number2;
    	int _number3;
    	(_number1, _number2, _number3) = GetThreeNumbers();
    	Console.WriteLine($"{_number1},{_number2},{_number3}");
    }
    
    public static (int, int, int) GetThreeNumbers()
    {
    	return (1, 56, 187);
    }

    Local Functions

    Local function, metot içerisinde metot kullanımıdır. Direkt örnekle açıklayayım, daha kolay olacaktır.

    NOT : Örnekte Tuples kullanıldığı için Tuples başlığındaki gibi yükleme işlemini yapmanız gerekiyor.

    static void Main(string[] args)
    {
    	// Fibonacci => 1, 1, 2, 3, 5, 8
    	// Mevcut değerin bir önceki değer ile toplamı bir sonraki
    	// değeri vermekte
    	Console.WriteLine(Fibonacci(6));
    	Console.Read();
    	// Sonuç (6-1) + 8 = 13
    }
    
    public static int Fibonacci(int x)
    {
    	if (x < 0)
    		throw new ArgumentException("Değer en az sıfır olmalı",
    									nameof(x));
    
    	return Fib(x).current;
    
    	(int current, int previous) Fib(int i)
    	{
    		if (i == 0) return (1, 0);
    		var (current, previous) = Fib(i - 1);
    		return (current + previous, current);
    	}
    }

    Literals, Ref. Returns, Exceptions

    static void Main(string[] args)
    {
    	// Sonuç => 5781231
    	Console.WriteLine(GetNumber());
    
    	// Referans Return
    	int[] numbers = { 1, 3, 5, 7, 9, 11 };
    	ref int position = ref Substitute(5, numbers);
    	position = -30;
    	Console.WriteLine(numbers[2]);
    
    	// Sonuç => Fırat
    	Employee employee = new Employee("Fırat");
    	Console.WriteLine(employee.Name);
    	// Sonuç => Hata / Exception
    	Employee employee2 = new Employee(null);
    	Console.WriteLine(employee.Name);
    
    	Console.Read();
    }
    
    // Literal: Altçizgi (underscore) seperator (ayırıcı)
    // olarak değil dönüş tipi olarak dönüyor
    private static int GetNumber()
    {
    	return 5_7_8_123_1;
    }
    
    // Reference Return örneği
    private static ref int Substitute(int value, int[] numbers)
    {
    	for (int i = 0; i < numbers.Length; i++)
    		if (numbers[i] == value)
    			return ref numbers[i];
    
    	throw new IndexOutOfRangeException("Bulunamadı!");
    }
    
    // Exception as expression örneği
    public class Employee
    {
    	public string Name { get; }
    	public Employee(string name) => Name = name ?? throw new ArgumentNullException();
    }

    Son olarak

    C# 7 yenilikler listesini Microsoft Documents üzerinden incelemek için => https://docs.microsoft.com/en-us/dotnet/articles/csharp/whats-new/csharp-7


older | 1 | 2 | (Page 3)