C# Exception Yapısı ve Custom Exception

5 Şub

Yazılım geliştirici olarak yazdığımız kodlarda oluşabilecek istenmeyen durumlar ile başa çıkmak durumundayız. Aksi taktirde yazılımlarımız zamanla kullanılamaz hale gelebilir. İstisnai durumların oluşturulması veya oluşturulmaması üzerine zamanla bazı fikirler gelişmiştir.

Microsoft tarafından oluşturulan eski yönergelerde istisnai durumlar ile başaçıkabilmek için bazı yönlendirmeler bulunmaktadır. Bunlardan biri de temel Exception sınıfından türetilmiş SystemException ve ApplicationException şeklinde iki kategori oluşturarak istisnai durumları gruplamaya çalışmaktır.

ApplicationException

ApplicationException sınıfı System.Exception sınıfından türetilmiş bir istisnai durum bildirim türüdür. Bu türü, uygulamamızın iç yapısı ile alakalı istisnai durumlar oluştuğunda bildirimler oluşturmak amacıyla oluşturulmuştur. İstisnai durumlar bir hata veya bir uyarı olabilir. Uygulamamıza özel istisnai durum sınıflarına ihtiyaç duyduğumuzda ApplicationException sınıfından durumumuza özel yeni bir sınıf türetebiliriz. Özel istisna (custom exception) sınıfları oluşturma konusunda Microsoft tarafından oluşturulan kılavuzlarda tecrübe aktarımları mevcuttur.

SystemException

SystemException sınıfı da System.Exception sınıfından türetilmiştir. .Net Framework üzerinde CLR tarafından üretilen tüm istisnalar bu sınıf altında toparlanmıştır. Bu sınıf ile sisteme ait istisnai durum bildirimleri oluşturulmaktadır ve fetal error diye adlandırılan önemli hataların oluştuğu istisnai durumlarda kullanılırlar. Örneğin veritabanı bağlantı hataları, dosya hataları, bellek kullanım hataları oluştuğu durumlarda SystemException sınıfından türetilmiş olan sınıflar kullanılır.

İstisnai durumların kod ile ayırımı

Kodlama sırasında try-catch bloğunda istisnai durumun türüne göre tavrımızı belirleyebiliriz.

   try{
       var data = fileService.ReadFromFile();
   }
   catch(ApplciationException e){
       // Bu kısımdaki hata kontrolüm altında devam et...
   }
   catch(SystemException e){
       // Bu hata sistemsel bir sorundur log tut ve tekrar istisna gönder
       throw;
   }

SystemException türünde bir durum meydana geldiyse bu hatalar mutlaka log servisleri ile kayıt altına alınmalıdır ve görmezden gelinmemelidir.

Runtime esnasında oluşan hataları System, uygulama tarafında oluşan istisnaları Application olarak ayırmak mantıklı gibi görünebilir. Ancak bir istisnanın ölümcül(fetal) olarak değerlendirilmesi istisnanın içinde bulunduğu şartlara bağlıdır. Çalışma zamanında oluşan her hatanın ölümcül(fetal) olduğu söylenemeyeceği gibi framework dışındaki geliştiricilerin yazdığı uygulama istisnaların hepsinin göz ardı edilebilir olduğu söylenemez.

Örneğin FileNotFoundException durumu oluştuğunda her zaman programı kapatmanın anlamı yoktur. Bu durum kullanıcıya uygun bir mesaj ile iletilebilir. Hatta bazı dosyaların eksikliğinin öngörülebilmesi için faydalıdır bile denilebilir.

Bu nedenle bu başlangıç kılavuzu çıkmadı ve Microsoft da zaten çıkarmak için zorlamadı. Öte yandan şu anda .Net Framework’te bile ApplciaitonException sınıfından türetilmiş birkaç istisna bulabilirsiniz. Günümüzde yeni bir istisna türü oluşturmak isteyen biri bu iki kategoriyi kullanmak yerine Exception temel sınıfından yeni bir istisna sınıfı oluşturmaktadır. Yani System ve Application kategorisini kullanan pek yoktur.

Özel istisna türleri (custom exceptions) oluşturmak

Exception durumları hakkında kısa bir zaman yolculuğu yaptıktan sonra asıl konumuz olan özel istisna sınıflarının oluşturulmasına gelmiş bulunuyoruz.

Günümüzde geliştiricilerin kendine özel istisna türlerini oluşturmak için belli bir hiyerarşi oluşturduğunu görmek mümkündür. Örneğin:

Burada iş kurallarına ait tüm istisnalar BusinessRuleException altında toplanmıştır.

Peki bu durumda özel istisna sınıfları oluşturmak uygun bir yöntem midir? Ya da InvalidOperationException, ArgumentException gibi özel türleri mi kullanmak gereklidir? Bu iki sorunun cevabı istisnaları kimin kullanacağıdır. Kullanacak olan sizseniz özel istisnalar oluşturmak korkunç bir düşüncedir. Burada unutulmamalıdır ki istisnalar kodda istisnai bir durumu belirtmek için kullanılır. Yani beklenmeyen bir durumu anlatmak için kullanılır.

Özel istisnalar ile ilgili bir kod yapısı oluşturulduğunda aşağıdaki gibi bir durum meydana gelecektir.

public string CreateCustomer(string name, string email)
{
   try
   {
     /* Creating a customer */
   }
   catch (EmailIsNotUniqueException)
   {
       return "The email provided already registered: " + email;
   }
   catch (CustomerNameIsInvalidException)
   {
       return "Customer name is invalid: " + name;
   }
   catch (CustomerAddressIsInvalidException)
   {
       return "Customer address is invalid";
   }
}

Bu kod yapısı C# diline uygun olsa da, hatta kullanışlı görünse bile iyi bir kullanım şekli değildir. Çünkü burada program akışı kontrol edilirken istisnalar kullanılmıştır ve istisnaların kontrol akışını sağlamak gibi bir görevi yoktur. Yukarıda da bahsettiğimiz gibi istisnalar istenmeyen bir durumu belirtmek için kullanılır.

Yazdığınız kodu sadece siz kullanacaksanız özel istisna sınıfları türetmenize gerek yoktur. İstisnalar yazılımınızdaki beklenmedik hataları bildirir ve işlemi tamamen sonlandırmanıza olanak verir. Ayrıca geçersiz bir girdi parametresinde olağan dışı bir durum yoktur ve bu sadece basit bir doğrulama hatasıdır.

Kendi oluşturduğunuz istisnaları, yürütme yığınının en üst düzeyindeki try-catch bloğunda yakalamak uygun bir yöntem olacaktır. İstisnaların burada log kayıtları tutulabilir ve kullanıcıya bir uyarı mesajı gönderilebilir. Örneğin Web Api için kullanıcıya 500 mesajı verilebilir.

Özel istisna türleri (custom exceptions) ve harici kütüphaneler

Yazdığınız kodu sizin dışınızda başka geliştiriciler de kullanacaksa istisnai durumlar için farklı bir yol izlenebilir.

Yazdığınız kütüphanede ortaya çıkan beklenmedik istisnai durumları nasıl ele alacağınızı siz bilmesenizde kütüphenenizi kullanan geliştiriciler bunu biliyor olabilir. Örneğin bir FTP client uygulaması kuruyorsunuz ve ana makine client uygulamaya cevap vermiyorsa bir çok kez deneme yapabilirsiniz. Bu durumda client uygulama kendi içerisinde sürekli yeniden bağlanmayı denerse işin içinde çıkılamaz. Bunun yerine kütüphanenizi kullanan geliştiriciye bağlantı hatası fırlatıldığında geliştirici bu durumda ne yapacağını kestirebilir. Sonuçta bağlantı sağlanamaması durumu ile nasıl başa çıkacağını kütüphane kullanıcısı bilir. Bu gibi durumlara karşı her kullanıcının alacağı önlem farklı olabileceğinden bu istisnai durumun özel bir tür olarak diğer istisnai durumlardan ayrılması gerekir. İşte özel istisna türlerinin yürütüleceği yer burasıdır. Oluşturulan özel istisnalar, kütüphane kullanıcılarının karşılaşabileceği her olası soruna karşı doğru tepki vermelerine yardımcı olur.

Özet

  • Özel istisna oluştururken SystemException ve ApplicationException gibi ketegori ayrımları kullanmak yerine Exception temel sınıfından yeni istisna sınıfları üretmek daha uygundur.
  • Eğer yazdığınız kütüphaneyi sizden başka kullanacak olan yoksa, özel istisna türleri oluşturmayın. Mevcut istisna sınıflarını kullanabilirsiniz. Ya da size özel tek bir  istisna türü oluşturarak her yerde kullanabilirsiniz.
  • Eğer bir kütüphane veya framework geliştiriyorsanız ilgili kütüphaneye özel istisna türleri oluşturun. Bu sayede kütüphane geliştiricisi olarak önceden kestiremeyeceğiniz durumlara karşı kullanıcılara bir emniyet önlemi sunmuş olursunuz.

Kaynak: http://enterprisecraftsmanship.com/2016/12/08/custom-exception-types/

LINQPad Programcıların Oyun Alanı

25 Haz

LINQPad yazılımı, SqlServer, Oracle, OData servisleri gibi veri kaynakları üzerinde LINQ sorgularını kullanarak sorgular çalıştırabilen ve C#, VB, F# gibi programlama dillerini destekleyen bir editördür.

LINQPad ile desteklenen diller ve gerçekleştirilebilecek operasyonlar seçenekler halinde geliştiricilere sunulmuştur.

  • C# Expression
  • C# Statements
  • C# Program
  • VB Expression
  • VB Statements
  • VB Program
  • SQL
  • ESQL
  • F#Expression
  • F# Program

Adsız

Geliştiriciler olarak hızlı bir şekilde denemeler yapmak istediğimiz durumlar olabilir. Bu durumda hemen Visual Studio arayüzünde bir proje oluşturarak ya da mevcut bir proje üzerinde merak ettiğimiz kodları çalıştırmak durumunda kalırız. Ancak LINQPad ile hızlı bir şekilde istediğimiz sonucu hemen görebiliriz.

Örneğin C# LINQ ile rasgele şifre üretmek için hemen bir deneme yapmak istersek:

Adsız

Yazmak istediğimiz ifadeleri tamamladıktan sonra sonucu görmek için sadece .Dump() extension metodunu çalıştırmak yeterlidir.

Harici kütüphaneleri ve Nuget paketlerini referans olarak LINQPad’e eklemek ve çalıştırabilmek mümkündür.

 

Entity Framework ve ORM araçlarının Lazy Loading mantığı

21 Tem

Entity Framework veya NHibernate veya benzeri ORM araçlarının Lazy Loading özelliği ilişkili tablolardan veri çekerken geliştiricilere büyük kolaylık sağlar. Her kolaylığın bir maliyeti vardır ve ilişkili tablolardan veri çekme işlemi sırasında oluşan maliyetin faturası veri tabanlarına yansıtılmaktadır. Bu yazıda veritabanlarından ilişkili veri çekimi sırasında ORM araçlarının nasıl sorgular oluşturduğunu incelemeye çalışacağız.

İlişkili Tablolar
İlişkili Tablolar

Yukarıdaki şema Blog tablosuna bağlı birçok Article olabileceği gibi, Article tablosuna bağlı birçok Tag olabileceğini göstermektedir. (Veritabanı MsSQL Express’dir.)

Bu yapıya göre bir Blog altındaki Article listesini görmek istediğimizde ve her Article için kaç Tag olduğunu listelemek istediğimizde nasıl bir yol izlemeliyiz? Bunu  Entity Framework kullanarak  incelemeye çalışalım.


public class Blog
{
     public int Id { get; set; }
     public string Name { get; set; }
     public virtual ICollection Articles { get; set; }

     public override string ToString()
     {
         return string.Format("{0} ({1})",Name, Articles.Count);
     }
}

public class Article
{
     public int Id { get; set; }
     public int BlogId { get; set; }
     public string Title { get; set; }
     public string Content { get; set; }

     public virtual Blog Blog { get; set; }
     public virtual ICollection Tags { get; set; }

     public override string ToString()
     {
        return string.Format("{0} ({1} Tags)", Title, Tags.Count);
     }
}

public class Tag
{
     public int Id { get; set; }
     public int ArticleId { get; set; }
     public string Name { get; set; }
     public virtual Article Article { get; set; }
}

public class BloggingContext:DbContext
{
     public DbSet Blogs { get; set; }
     public DbSet Articles { get; set; }
     public DbSet Tags { get; set; }
}

Bu kısımda Entity Framework için veritabanı tablolarını temsil eden tipler oluşturulmuştur. App.config veya Web.config dosyaları içerisinde connectionString ayarlamalarını yaptıktan sonra BloggingContext nesnesi ile veritabanında işlemler gerçekleştirilebilmektedir. Bu işlem aşağıdaki gibi yapılmaktadır.

 static void Main(string[] args)
 {
    using (var context = new BloggingContext())
    {
       foreach (var blog in context.Blogs.ToList())
       {
          Console.WriteLine(blog);
          foreach (var article in blog.Articles)
          {
              Console.Write("\t");
              Console.Write(article);
              Console.Write("\n");
          }
       }
    }
 }
Run
Run

Öncelikle Blog’lar listeleniyor ve parantez içinde her Blog türüne bağlı Article sayısı yazdırılıyor. Article satırına da her Article türüne bağlı Tag sayısı yazdırılıyor.

Bu işlem gerçekleşene kadar acaba veritabanında neler olup bitiyor? Bunu anlamak için Express Profiler aracından faydalanabilirsiniz. Express Profiler aracı veritabanına giden tüm sorguları yakalayabilen bir özelliğe sahiptir.

Kodumuzu çalıştırdığımızda Express Profiler penceresinde bir dizi işlemler raporlanacaktır.

Express Profiler
Express Profiler

Entity Framework öncelikle veritabanının var olup olmadığını sorgular. Daha sonra ilgili tabloların olup olmadığını sorgular. Daha sonra MigrationHistory tablolarını sorgular. Derken bizi ilgilendiren kısım olan Blog listesini çeken sorguyu oluşturulur.

Adsız

Bu sorgu sonrasında Blog listesindeki ilk Blog’a bağlı Article listesi seçilir.

Adsız

Article listesi geldikten sonra ilgili Article için Tag listesi çekilir.

Adsız

 

Bu işlem döngü şeklinde devam eder gider.

Şu anda listelediğim örnek tablolarda toplamda 10 veya 15 veri vardır. Bu işlem yüz binlerce kayıt barındıran tablolarda yapılmaya çalışıldığında epeyce maliyetli olabilir. Maliyeti düşürmek adına JOIN ile oluşturulabilecek ham SQL sorguları kullanmak daha ucuz bir yöntem olacaktır.

SELECT B.Name, COUNT(A.Id)
FROM Blogs as B
LEFT JOIN Articles as A
ON A.BlogId=B.Id
GROUP BY B.Name

ORM araçlarına savaş açmak yerine uygun ve yerinde çözümler üretmek hayat kurtarıcı olabilir.

Güncelleme: 25.07.2015, SQL JOIN sorgusu eklendi.

C# MSMQ Mesaj Yönetimi, Okuma Yazma İşlemleri

21 Haz

MSMQ teknolojisi ile alakalı bir önceki yazıda MSMQ tanıtımını yapmış ve Windows işletim sistemlerine nasıl dahil edildiğini incelemiştik.

Bu yazıda ise mesajların MSMQ kuyruğuna nasıl yazıldığını ve kuyruktaki mesajların nasıl okunduğunu incelemeye çalışacağız.

Öncelikle mesaj nedir bundan bahsedelim. MSMQ teknolojisindeki mesaj kavramı aslında bir programlama dili ile oluşturulan nesnelerin serileştirilmiş halleridir. Bir nesne binary veya xml gibi formatlarda serileştirilebilir. Serileştirilmiş nesneler MSMQ gibi mesaj tabanlı iletişim ortamlarında mesaj olarak değerlendirilir.

MSMQ sisteminde mejsalar kuyruk denilen bir dizgede tutulur. Kuyruklar günlük hayattaki posta kutularına benzer. Postacı gelip zarfı posta kutusuna bırakır. Daha sonra ev sahibi gelip kutudaki zarfı açarak mesajı okuyarak ne yapacağını anlar ve gereğini yapar.

C# programlama dili ile MSMQ kuyruğundaki mesajları yönetmek mümkündür. Windows işletim sisteminde MSMQ kuyruğunu bilgisayar yönetimine girerek Private Queue seçeneğinden görüntüleyebiliriz.

MSMQ
MSMQ

.Net Framework içerisinde System.Messaging namespace altında mesaj trafiğini yönetebilecek tipler bulunmaktadır.

MessageQueue tipine ait üyeler yardımıyla sistemde bir kuyruk mevcut mu diye kontrol edilebilir, mevcut değilse yeni kuyruk oluşturulabilir. Mevcut kuyruğa bir mesaj eklenip, kuyruktan bir mesaj alınabilir. Aşağıdaki örnek kod ile kuyruğa mesaj yazma işlemi gerçekleştirilmektedir.

MessageQueue messageQueue = null;

if (MessageQueue.Exists(@".\Private$\EmailQueue"))
{
    messageQueue = new MessageQueue(@".\Private$\EmailQueue");
}
else
{
    // Kuyruk oluştur.
    MessageQueue.Create(@".\Private$\EmailQueue");
    messageQueue = new MessageQueue(@".\Private$\EmailQueue");
}

messageQueue.Send("Bu ilk bir MSMQ mesajıdır", "Title");

Kuyruktaki mesajları okumak senkron veya asenkron şekilde yapılabilmektedir. MessageQueue tipine ait aşağıdaki metodlar:

  • BeginPeek()
  • BeginReceive()

asenkron şekilde mesajları okumaya olanak sağlar. bu mesajların override edilmiş şekilleri burada mevcuttur.

BeginPeek() metodu çağrılmadan önce PeekComplated event handler oluşturmak gerekir ki okunan mesajın içeriğine erişebilelim. Aynı şekilde BeginReceive() metodu çağrılmadan önce ReceiveComplated event handler oluşturmak gerekir. BeginPeek() ile alınan mesajlar kuyruktan silinmezken BeginReceive() ile okunan mesajlar kuyruktan silinir. Bu fark, süreçleri yönetmek açısından önemlidir. Aşağıdaki örnek kod, tek bir mesajın kuyruktan asenkron olarak alınmasını sağlar. BeginReceive() kullanıldığı için alınan mesaj kuyruktan silinecektir.

MessageQueue messageQueue = null;

if (MessageQueue.Exists(@".\Private$\EmailQueue"))
{
    messageQueue = new MessageQueue(@".\Private$\EmailQueue");
    messageQueue.ReceiveCompleted += new
           				ReceiveCompletedEventHandler(EmailReceived);
    messageQueue.BeginReceive();
}

private static void EmailReceived (Object source,
            ReceiveCompletedEventArgs asyncResult)
{
    MessageQueue mq = (MessageQueue)source;
    Message m = mq.EndReceive(asyncResult.AsyncResult);
    Console.WriteLine("Message: " + (string)m.Body);
}

MessageQueue tipinde senkron bir şekilde mesaj almak için aşağıdaki metodları kullanılabilir:

  • Peek()
  • Receive()
  • GetAllMessages()

Yani Peek() veya Receive() metodu çağrıldığında kuyruktan bir mesaj gelene kadar başka işleme geçilmez. Oysa asenkron metodlarda BeginPeek() veya BeginReceive() komutlarından sonra başka işlem varsa onlar yürütülebilmekteydi.

GetAllMessages() metodu kuyruktaki tüm mesajları getirmek için kullanılır.

 MessageQueue queue = new MessageQueue(@".\Private$\EmailQueue");

 Message[] msgs = queue.GetAllMessages();

 foreach(Message msg in msgs)
 {
     Console.WriteLine(msg.Body);
 }

Mesaj kuyruğuna bir text yerine bir nesneyi göndermek mümkündür. Bu işlem için öncelikle serileştirilecek olan tipin belirlenmesi gerekmektedir. Serileştirilecek olan tip aşağıdaki şekliyle Email adında belirlenmiş ve [Serialize] attribute ile imzalanmıştır.

[Serialize]
public class Email{
     public string From {get; set;}
     public string To {get; set;}
     public string Body {get; set;}
}

Bu nesnenin bir örneğini kuyruğa eklemek için aşağıdaki gibi bir yöntem izlenir.

Email mail = new Email{
   From = "sender@mail.com",
   To = "receiver@mail.com";
   Body = "Merhaba bu bir test mesajıdır.";
};
MessageQueue messageQueue = null;

if (MessageQueue.Exists(@".\Private$\EmailQueue"))
{
    messageQueue = new MessageQueue(@".\Private$\EmailQueue");
}
else
{
    // Kuyruk oluştur.
    MessageQueue.Create(@".\Private$\EmailQueue");
    messageQueue = new MessageQueue(@".\Private$\EmailQueue");
}

Message message = new Message();
message.Formatter = new BinaryMessageFormatter();

messageQueue.Send(message);

Temel olarak MSMQ mesaj yönetimi bu şekilde yapılmaktadır. Buradaki örnekler yazma ve okuma işlemlerini gösteren tek bir uygulama gibi anlaşılabilir. Ancak dağıtık mimarilerde kuyruğuna yazım işlemini bir uygulama yaparken, kuyruğu sürekli kontrol etme işlemini işletim sistemine bağlı bir servis sağlıyor olabilir. Ya da zamanlanmış görev mantığı ile çalışan bir client uygulama da kuyruktaki mesajları okuyarak gerekli görevleri yerine getirebilir. Senaryoları tasarlamak tamamen ihtiyaca ve beceriye kalmıştır.

Bir sonraki yazıda görüşmek dileğiyle.

Microsoft Message Queuing – MSMQ Nedir?

12 Haz

Microsoft Message Queuing ya da kısa adıyla MSMQ teknolojisi, aralarında sürekli bir bağlantı gerektirmeyen dağıtık sistemlerde uygulamaların emniyetli bir şekilde iletişim kurmalarını sağlayan bir protokoldür.

Dağıtık sistemlerde çalışan bir uygulama MSMQ üzerinde kuyruğa bir mesaj gönderir ve sıradaki işlemlerden kendi iç sürecini işletmeye devam eder. Sistemde bu mesaja ihtiyacı olan diğer bir uygulama bu kuyruğa giderek ilgili mesaj varsa alır ve kendi sürecini başlatır. Aşağıdaki resimde bu durum bir grafik üzerinde ifade edilmiştir.

MSMQ
MSMQ

Bu sayede birbirinden bağımsız çalışan iki ayrı sistem, birbirlerini beklemeden görevlerini yerine getirebilmektedir.

Örneğin bir web sitesi üzerinde yapılan işlemler sonrasında kullanıcı bilgilendirme amaçlı E-Posta gönderiliyor olsun. E-Posta gönderme işlemi ayrı bir mail sunucu üzerinden yapılacaktır. Kullanıcı, bir üyelik formunu doldurup gönderdikten sonra sürecin tamamlanmasını beklemeye başlar. Bu aşamada form bilgileri veri bankasına yazılır ve kullanıcıya bir bilgilendirme mesajı gönderilir. Ancak E-Posta sunucusu geç yanıt verirse veya arızalı durumda ise kullanıcının kayıt süreci yarım kalacaktır ve eksik bir işlem yapılmış olacaktır. Bunun sebebi web uygulamasının, ayrık bir sistem olan E-Posta sunucusuna bağımlı olmasıdır. Bu gibi durumları garanti altına alabilmek için kullanıcıya gönderilecek olan E-Posta bilgileri kayıt sürecinde MSMQ sistemi üzerinde kuyruğa eklenir. Bir başka uygulama bu kuyruğu kontrol ederek E-Posta gönderme işlemlerini gerçekleştirir. Yani iki ayrık sistem birbirinden izole hale getirilerek çalışma süreçleri birbirini etkilememiş olur.

MSMQ teknolojisinin kullanım amacı, dağıtık sistemlerde asenkron ve birbirinden bağımsız süreçler oluşturarak performans artışı sağlamaktır. Dağıtık sistemde çalışan bileşenlerden bir veya birkaçının devre dışı kalması durumunda sistemin iç süreçlerinin devam edebilmesi garanti altına alınabilmektedir. Ağa sürekli bağlı olmadan yürütülen işlemlerde sonuçlar sisteme mesaj şeklinde aktarılabilir ki buna sahada satış yapmak için kullanılan uygulamalar örnek verilebilir.

Kullanım alanları:

  • Kritik öneme sahip uygulamalar. Örneğin E-Ticaret, Bankacılık gibi.
  • İş akışlarının oluşturulduğu uygulamalar.
  • Gömülü sistemler.
  • Sahada satış, sipariş uygulamaları.

MSMQ teknolojisi işletim sistemi üzerinde Windows özelliği olarak gelmektedir. İsteğe bağlı açılabilen bir özelliktir. Kişisel bilgisayar ve sunucu işletim sistemlerine göre birçok versiyona sahiptir.  Aşağıdaki listede işletim sistemi türlerine göre MSMQ versiyonlarının gelişimi sunulmuştur.

MSMQ Versiyonları:

  • MSMQ 1.0, Microsoft Windows NT, Windows 95, 98 sürümleri üzerinde çalışan versiyondu.
  • MSMQ 2.0, Microsoft Windows 2000 üzerinde çalışan versiyon.
  • MSMQ 3.0, Microsoft Windows XP Professional ve Server 2003 ailesi üzerinde çalışan versiyondur.
  • MSMQ 4.0 Windows Vista ve Windows Server 2008 üzerinde çalışır.
  • MSMQ 5.0 Windows 7 ve Windows Server 2008 R2 üzerinde çalışır.
  • MSMQ 6.0 Windows 8 ve Windows Server 2012 üzerinde çalışır.
  • MSMQ 6.3 Windows Server 2012 R2 üzerinde çalışır.

Windows 7 veya Windows 8 gibi kişisel işletim sistemlerinde MSMQ özelliğinin açılması Denetim Masası -> Programlar ve Özellikleri -> Windows Özelliklerini Aç veya Kapat linkinden açılan pencereden yapılmaktadır.

Windows 8 MSMQ
Windows 8 MSMQ

Windows 2008 veya 2012 gibi sunucu işletim sistemlerinde ise Server Manager -> Features -> Add Feature linkinden açılan pencereden seçerek yapabiliriz.

Windows 2008
Windows 2008

MSMQ özelliği işletim sistemine eklendikten sonra Bilgisayar Yönetimi menüsünden görüntülenebilmektedir.

MSMQ
MSMQ

Bir sonraki yazıda görüşmek üzere.

Kaynak: https://msdn.microsoft.com/en-us/library/ms711472(v=vs.85).aspx

C# LINQ ile Rastgele Şifre Üretmek

4 Nis

Bu yazıda System.Linq kütüphanesinden faydalanarak rastgele şifre üretmenin ne kadar pratik ve basit olduğunu inceleyeceğiz. Bu pratik çözüme burada rastladım ve herkese faydalı olacağını tahmin ederek paylaşmak istedim.

var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
var random = new Random();
var result = new string(
    Enumerable.Repeat(chars, 8)
              .Select(s => s[random.Next(s.Length)])
              .ToArray());

Olayın gelişimini incelediğimizde Enumerable sınıfının Repeat fonksiyonundan faydalanıldığını görüyoruz.

Enumerable.Repeat fonksiyonunun syntax düzeni şu şekildedir:

public static IEnumerable<TResult> Repeat<TResult>(
   TResult element,
   int count
)

Çalışma şekli ise TResult türünde Count kadar tekrar eden bir yığın üretecek şekilde ayarlanmıştır. Örneğin 15 tane “Okul” sözcüğü üret şeklide çalışır.

Yukarıdaki şifre üretmek için oluşturulan örnekte bizim verdiğimiz bir diziden her defasında rastgele bir karakter çekildiği için tekrarlı veri yığını oluşmuyor. Sonuç olarak count değeri kadar karakter içeren bir şifre oluşturabiliyoruz.

.Net Framework Gelişim Tarihine Genel Bakış

7 Mar

Microsoft .Net Framework ile ilgili tarihi geçmişe bir göz atarak eskiden günümüze(2015) yani 4.5.1 framework sürümüne kadar nasıl bir gelişimin olduğunu genel hatlarıyla incelemeye çalışalım.

.Net Framework 1.0: 2002 yılında duyurulmuş ilk versiyonsdur. Visual Studio .Net geliştirme aracı ile birlikte sunulmuştur.

.Net Framework 1.1: 2003 yılında duyurulan bu versiyon ile birlikte Visual Studio 2003 geliştirme aracı da piyasaya sürülmüştür. .Net Framework 1.1 ile birlikte ilk defa Asp.Net Mobile control araçları denenmiştir. Ayrıca birden fazla ve farklı Framework sürümünü aynı bilgisayarda çalıştırabilme özelliği olan side-by-side özelliği eklenmiştir. Güvenlik ile ilgili yeni gelişmeler eklenmiştir.

.Net Framework 2.0: 2005 yılında Visual Studio 2005 geliştirme aracıyla birlikte duyurulmuştur. Bu framework ile birlikte Generic, Nullable tipleri, IPV6 desteği ve CLR 2.0 gibi önemli özellikler eklenmiştir.

.Net Framework 3.0: 2006 yılında duyurulmuş olup Visula Strudio 2005 üzerinden devam etmiştir. Bu sürüm ile birlikte WCF(Windows Communication Framework), WPF(Windows Presentation Framework), WF(Workflow Foundation) gibi yenilikler geliştiricilerle buluşturulmuştur. Bu yenilikler ile iletişim, sunum  ve iş akışları gibi ayrımlar ilk defa belirgin bir şekilde altyapı olarak yapılmış oldu.

.Net Framework 3.5: 2008 yılında Visual Studio 2008 gelitirme aracı ile beraber duyurulmuştur. LINQ ve Addin/Plugin Model gibi özellikler eklenmiştir.

.Net Framework 4.0: 2010 yılında Visual Studio 2010 il birlikte duyurulan bu sürümde bir çok yeni özellik eklenmiştir. Parallel Computing, Code Contracts, Lazy Initializations, Dynamic Language RuntimeIn-process side-by-side hostingBackground garbage collection ve CLR 4.0 şeklinde önemli eklemeler yapılmıştır.

.Net Framework 4.5: 2012 yılında Visual Sturio 2012 ile beraber duyurulmuştur. Paralel Programlama üzerinde yeni gelişmeler async/await yöntemi, asenkron işlemler, 64-bit platformlarda 2 gigabayt’tan (GB) büyük diziler için destek, Sıkıştırılmış dosyaların boyutunu azaltmak için Zip sıkıştırma işlevinde geliştirmeler yapılmıştır.

.Net Framework 4.5.1: 2013 yılında Visual Studio 2013 ile birlikte duyurulmuştur. Derlemeler için otomatik bağlama yeniden yönlendirme, .NET Framework güncelleştirmelerinden sonra daha hızlı uygulama başlatma, çok çekirdekli JIT geliştirmeleri ve ASP.NET uygulama askıya alma gibi ek performans artışları yapılmıştır. Sunucularda arka plan çöp toplama işlemi ile daha iyi performans sağlanmıştır.

Prime Factors Kata C# – Kod Kata

28 Tem

Prime Factors Türkçe olarak Asal Çarpanlar şeklinde tercüme edilebilir. Prime Factors Kata’sını geliştirirken bir sayının asal çarpanlarının bulunması hedeflenmektedir. Bir sayının asal çarpanları bulunup liste şeklinde kullanıcıya verilmektedir. Aşağıdaki listede örnek olarak verilen sayıların çarpanları listelenmiştir.

Prime Factors (Asal Çarpanlar)

1 => [ ]
2 => [2]
3 => [3]
4 => [2,2]
5 => [5]
6 => [2,3]
7 => [7]
8 => [2,2,2]
9 => [3,3]
10 => [2,5]
24 => [2,2,2,3]

ASP.NET MVC Projesinde Dependency Injection Uygulanması

30 Haz

Daha önce hazırladığım Dependency Injection Tasarım Deseni başlıklı yazıda, yazılım tasarımında sınıfların birbirine olan bağımlılıklarını esnetmeyi ve bağımlılıkların sınıf dışından enjekte edilmesini incelemiştik. Bu yazımızda ise konunun bir örnek uygulaması niteliğinde olan ASP.NET MVC uygulamalarında Dependency Injection uygulamasını inceleyeceğiz.

Bu yazımızdaki örnek uygulamamızı geliştirirken, soyut sınıflar ile somut sınıflar arasındaki bağlantıyı kurarken ve somut nesne oluştururken IoC Container denen yardımcı kütüphanelerden faydalanacağız. Yine bu örnek uygulamada IoC Container kütüphanesi ile  somut nesnelerin kullanıcı(client) sınıf içerisinde “new” anahtar sözcüğü ile oluşturmak yerine, IoC Container tarafından oluşturulduğunu göreceğiz.

Örnek Uygulama

Örnek uygulamamızda ASP.NET MVC controller sınıfına Dependency Injection tarasım deseni ile bağımlılıkları dışarıdan soyut nesneler(interface veya abstract) yardımıyla vererek uygulamayı çalıştırmayı deneyeceğiz.

Öncelikle Controller sınıfımızı tanımlayarak işe başlayabiliriz.

public class HomeController : Controller
{
    private readonly IProductService productService;

    public HomeController(IProductService productService)
    {
        this.productService = productService;
    }
    public JsonResult Index()
    {
        IEnumerable<Product> products = productService.GetBestSellers();

        return Json(products, JsonRequestBehavior.AllowGet);
    }

}

Gördüğünüz üzere, Controller sınıfında hiç bir şekilde nesne oluşturma işlemi gerçekleştirilmiyor. Dışarıda oluşturulan ProductService nesneleri Controller sınıfı içerisine enjekte ediliyor. IProductService tipi bir interface’dir. Bu interface tipini uygulayan sınıflar HomeController içerisinde çalışabilir. IProductController tipindeki nesneler constructor metodu yardımıyla sınıf içerisine alınıyor.

ASP.NET MVC Controller sınıflarının varsayılan(default) halleri çalışma zamanında parametresiz constructor metodlarını ararlar. Bu tanımlama ASP.NET DefaultControllerFactory içerisinde belirlenmiştir. ASP.NET MVC open source olduğundan isteyen MVC kodlarını açıp inceleyebilir. Biz constructor seviyesinde injection işlemi yapacağımızdan DefaultControllerFactory sınıfının GetControllerInstence metodunu ezerek yani yeniden tanımlayarak istediğimiz formata getirmeliyiz.

Bu tanımlamayı yapmadan önce uygulamada kullanacağımız NInject kütüphanesinden bir iki cümle ile bahsedelim. Ninject kitüphanesi bir konteynır olarak çalışır. Soyut nesneler ile somut nesnelerin eşleştirildiği ve istendiğinde somut nesnelerin(new) oluşturulduğu kütüphanelerdir.

public class NinjectControllerFactory : DefaultControllerFactory
{
     private readonly IKernel kernel;

     public NinjectControllerFactory()
     {
         kernel = new StandardKernel(new NinjectBindingModule());
     }

     protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
     {
         return controllerType == null ? null : (IController)kernel.Get(controllerType);
     }
}

public class NinjectBindingModule : NinjectModule
{
     public override void Load()
     {
         Kernel.Bind<IProductService>().To<ProductService>();
     }
}

Burada tanımlanan kod parçasında anlatılmak istenen şey DefaultControllerFactory metodunun Controller Instance oluştururken karşılaşacağı parametresiz constructor metodu oluşturma hatasını engellemektir. Ninject aracılığı ile Controller tipine göre bir nesne oluşturuyor. Örneğin HomeController için controllerType HomeController olacaktır ve constructor metodunda IProductService interface tipini parametre olarak alacaktır. HomeController tipinde bir nesne oluştururken constructor metodda karşılaştığı parametreyi Kernel bildiği için hemen nesnesini oluşturarak Controller sınıfına vermektedir.

Artık Global.asax sınıfı içerisine bu yapıyı tanıtma işlemi kaldı. Onu da şu şeklide gerçekleştirebiliriz.

public class MvcApplication : System.Web.HttpApplication
{
     protected void Application_Start()
     {
        //diğer tanımlamalar...

        ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
     }
}

Uygulamayı çalıştırdığımızda çıktı olarak şu şekilde bir JSON veri dönecek:

[{"Name":"Notebook"},{"Name":"PC"}]

Örnek uygulamanın kodlarını SkyDrive üzerinden paylaştım. Bir sonraki yazıda görüşmek üzere.

Kaynak Kodlar: Burada

Operatörlerin Aşırı Yüklenmesi (Operator Overloading C#)

27 May

Bu yazımızın konusu geliştiriciler tarafından oluşturulan sınıflar veya yapılar(struct) üzerinde operatörlerin aşırı yüklenmesidir. Operatörlerin aşırı yüklenmesi, bir operatörün bir nesne için bizim istediğimiz şekliyle çalışabilecek hale getirilmesidir diyebiliriz. Örneğin bir (+) operatörü varsayılan olarak iki sayının toplamı bulmak için veya iki ayrı metnin birleştirilmesi için kullanılır. Bazen yazdığımız sınıflara ait nesneler üzerinde operatörleri kullanmak isteriz. Bu durumda sınıfımızda bir takım değişiklikler yapmak zorundayız.

Bir örnek uygulama üzerinden operatörlerin aşırı yüklenmesini incelemeye çalışalım. Örneğimizin senaryosunda aşırı yükleme işlemini uygulamak için Price adında bir sınıf oluşturup bu sınıfa Cost adında bir property ekleyelim. İki farklı Price nesnesi üzerinden (+) gibi operatörleri aşırı yüklemeye çalışalım.

public class Price
{
      public double Cost { get; set; }

      public static double operator +(Price e1, Price e2)
      {
          return e1.Cost + e2.Cost;
      }
}

En basit gösterimi ile Price sınıfında (+) operatörünün aşırı yüklenmiş halini görüyoruz. Bir operatörün aşırı yüklenmesi bir takım kurallar içermektedir. Bunlar:

  • Operatör fonksiyonu static olmalıdır.
  • Operatör fonksiyonu, aşırı yüklenecek operatörün anahtar kelimesini belirtmelidir.
  • Operatör fonksiyonunun parametreleri, işlenecek tiplerdir.
  • Operatör fonksiyonunun geri dönüş türü belirlenmelidir.

Bu sınıf için (+) operatörünün kullanımı, şu şeklide opacaktır.

 Price p1 = new Price { Cost = 40.10 };
 Price p2 = new Price { Cost = 40.10 };

 var sum = p1 + p2; // sum = 80.20

Artık (+) operatörü, Price nesneleri için bir işleve sahip. Bu işlev, Price nesnesinin Cost parametrelerinin toplamını almasıdır.

Eğer aşırı yükleme işlemini yapmasaydık ve (+) operatörünü aynı şekliyle Price nesnesinde kullanmaya çalışsaydık şu şekilde bir hata alacaktık: “Operator ‘+’ cannot be applied to operands of type ‘OperatorOverrideApp.Price’ and ‘OperatorOverrideApp.Price

Price nesnesine int, double, float gibi built-in tipler ile toplamak istersek sadece işlenen argümanlarda şu şeklide bir değişiklik gerçekleştirmek yeterli olacaktır.

public static double operator +(Price e1, double e2)
{
     return e1.Cost + e2;
}

Bu şekilde, kendi sınıflarımızda operatörlerin aşırı yüklenmesi işlemini incelemeye çalıştık. Örnek uygulamaya ait kodlara buradan ulaşabilirsiniz.