Codeproject Makale-1 Test Driven Developmnet

31 Oca

Merhaba,

Dünyanın çok çeşitli yerlerinden geliştiricilerin makalelerini yayınladığı uluslarası bir konumda olan makale sitesi codeproject artık benim yazdığım bir makaleye de ev sahipliği yapıyor. Değişik bir tecrübe olması açısından ve hep tüketen konumda olmamak adına bir makale üretip yayınlamayı düşündüm ve bu düşüncemi gerçekleştirdim.

Sitede junior developer seviyeden senior developer seviyesine hatta team leader seviyesine kadar ulaşmış kişiler makale yayınlamakta.  Üye sayısının çok fazla olması sebebiyle (ki en son 8 milyon civarıydı, şu an kaçtır bilemiyorum) yazılan makalelere anında yorumlar gelmesi gerçekten çok hoş bir durum. Gelen yorumlardaki değişik fikirler, eleştiriler gelişiminize şüphesiz katkı sağlıyor.

Yazdığım makalenin konusu Test Driven Development ile geliştirilen bir Factorial uygulaması.

Uygulamanın akışı baştan sona detaylarıyla anlatılmakta ve örnek uygulama kodlarıyla birlikte verilmektedir.

Ortam benim hoşuma gitti :). Herkese tavsiye ederim. Makaleye buradan ulaşabilirsiniz.

Herkese kolay gelsin tekrar görüşmek dileğiyle…

WCF Data Service ile Database Verisine Erişim

28 Oca

Bir önceki WCF Data service ile ilgili yazımızda herhangi bir veri kaynağına bağlı olmayan veri kolleksiyonlarına servisler aracılığıyla erişimi incelemiştik. Bu yazıda ise bir veri kaynağına bağlı olan EDMX modeldeki veri kümelerine WCF data servisleri aracılığıyla erişmeyi inceleyeceğiz.

İlk olarak WcfDatabaseDataservice adında yeni bir Web projesi eklenir. Projeye StoreModel adında yeni bir ADO.Net Entity Data Model eklenir.

Model üzerindeki veri kümelerine erişmek için projeye StoreService adında bir WCF data service eklenir.


   public class StoreService : DataService<StoreEntities>
   {
       public static void InitializeService(DataServiceConfiguration config)
       {
          config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
          config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
       }
   }

Servis tipinin  DataService<StoreEntities> generic tipinden türetildiği görülmektedir. Yani StoreEntities içindeki veri kümelerine erişilecek.

SolutionExplorer penceresindeki StoreService.svc dosyasına sağ tıklayıp “View in Browser” seçeneği ile servise web browser üzerinden erişebiliriz.

Servis aracılığıyla Collection düğümlerindeki veri kümelerine, kendine ait URI’ler yardımıyla erişilebilir. Örneğin kategorilere erişmek için http://localhost:10182/StoreService.svc/Categories kullanılabilir.

Model üzerindeki stored procedure kullanılmadan önce Function Import işleminden geçirilmelidir. Bunun için Model Browser penceresinden ilgili stored procedure ki örneğimizdeki store procedure adı GetProductSP’dir. Bu procedure sağ tıklayıp Add Function Import tıklanır ve açılan pencerede Get Column Information butonu tıklanarak kolon bilgileri listelenir. Ardından Create New Complex Type butonu ile GetProductBySP_Result kompleks tipi oluşturulur.

WCF data servisi üzerinden GetProductSP function import’una direk erişilemez. Ancak StoreService sınıfına bir metod ekleyerek, metod üzerinden erişim sağlayabiliriz. Servis sınıfına eklenen metodlar servis operasyonları(Service Operations) olarak adlandırılır. Servis operasyonları parametre alabilir. Fakat servis oprasyonlarının geri döndürdüğü değerler Ienumerable, Iqueryable veya void tipinde olmalıdır.

Servis operasyonları WebGet veya WebInvoke attribute ile imzalanmalıdır. WebGet attribute, HTTP GET ile çalışır, WebInvoke ise HTTP POST ile çalışır. Aşağıdaki örnek, WebGet attribute ile imzalanmış bir servis operasyonunun URI yardımıyla nasıl çalıştırıldığını göstermektedir.

public class StoreService : DataService<StoreEntities>
{
        public static void InitializeService(DataServiceConfiguration config)
        {
           config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
           config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
           config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
        }

        [WebGet]
        public IQueryable<GetProductBySP_Result> ProductsBySp()
        {
           using (StoreEntities context = new StoreEntities())
           {
              return context.GetProductBySP().ToList().AsQueryable();
           }
        }
    }

Servis ayarlamalarının yapıldığı DataServiceConfiguration sınıfının servis operasyonlarının yetkilerini belirlediği bir metod vardır. Bu metod setServiceOperationAccessRule metodudur.

Metodu browser üzerinden http://localhost:10182/StoreService.svc/ProductBySp şeklinde çağırılır.

Sonuç olarak servis aracılığı ile modeldeki bir “stored procedure” erişimini incelemiş olduk.

Umarım faydalı bir yazı olmuştur.

WCF Data Servis Custom Collection Uygulaması

25 Oca

WCF data servisleri mimarisini bir önceki yazımızdada kısaca özetlemiştik. Bu yazımızda ise bir WCF data servisinin nasıl oluşturulduğunu ve kendi özel sınıfımıza ait bir kolleksiyona bu servis üzerinden erişildiğini inceleyeceğiz.

Visual studio ortamından WcfCustomDataService adında yeni bir web projesi başlatarak bu proje üzerinde incelemelerimizi yapabiliriz.

Projemize Product ve Category adında iki yeni sınıf ekliyoruz.


    [DataServiceKey("Id")]
    public class Product
    {

        public int Id { get; set; }
        public string Name { get; set; }

    }

    [DataServiceKey("Id")]
    public class Category
    {
        public int Id { get; set; }
        public string Name { get; set; }

    }

Sınıflarımıza baktığımızda DataServiceKey ile servis anahtar property değerinin belirlendiğini görüyoruz. Bu attribute ile belirlenen anahtar özellik sayesinde OData, istenen elemana ulaşabilmektedir. DataServiceKey attribute System.Data.Services.Client.dll içindeki System.Data.Services.Common alanında bulunmaktadır. Eğer bu dll projenize dahil değilse eklemeniz gerekecektir.

Servisimiz ile ulaşabileceğimiz kolleksiyonları bulunduracağımız Store adında bir sınıf ekleyerek içerisine kolleksiyonlarımızı bu sınıf içerisine yerleştirebiliriz. Store içerisine ProductSet ve CategorySet adında iki adet generic IQueryable kolleksiyon ekliyoruz. Generic tip IQueryable olmalıdır.

    public class Store
    {
        public IQueryable<Product> ProductSet
        {
          get
          {
             return new List<Product>
             {
               new Product{ Id=1, Name="Game Console" },
               new Product{ Id=2, Name="IBM Computer"},
               new Product{ Id=3, Name="Baby Toy"}

             }.AsQueryable();
          }
        }

       public IQueryable<Category> CategorySet
       {
         get
         {
            return new List<Category>
            {
               new Category{ Id=1, Name="Game" },
               new Category{ Id=2, Name="Computer"},
               new Category{ Id=3, Name="Toys"}

            }.AsQueryable();
         }
       }
   }

Şimdi projemizde kullanacak olduğumuz servisi eklemeye geldi. WCF data servis ekleme işlemi için projemize sağ tıklayıp Add -> New Item şeçeneği yardımıyla  StoreService.svc adında bir “WCF Data Service” ekliyoruz. Servisimiz eklendiğinde kod kısmını aşağıdaki şekilde düzenliyoruz.

   public class StoreService : DataService<Store>
   {
       public static void InitializeService(DataServiceConfiguration config)
       {
          config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
          config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
       }
   }

StoreService sınıfı DataService<Store> generic tipinden türetilmiştir. Burada Store tipi bizim daha önceden tanımladığımız kolleksiyonları tutmaktadır.

InitializeService metodu DataServiceConfiguration tipinde servis ayarlarını belirleyen bir parametre almaktadır.

DataServiceConfiguration  tipinin SetEntityAccessRule metodu iki parametre alamktadır. Birinci parametre string türündedir ve entity adını belirler, ikincisi ise EntitySetRights numaralandırıcı tütündedir ve entity erişim kurallarını belirler.

Örnek:

            config.SetEntitySetAccessRule("ProductSet", EntitySetRights.AllRead);
            config.SetEntitySetAccessRule("CategorySet", EntitySetRights.None);

Yukarıda örnekte belirlenen kuralda, ProductSet için tüm okuma yetkileri verilmiş, CategorySet için tüm erişimler kısıtlanmıştır. Bu durumda servis çağrıldığında sadece ProductSet verilerine erişilebilmektedir.

Biz bu örnekteki ayarları kullanmadan  varsayılan ayarlar ile devam ediyoruz.

Servisi hazırladıktan sonra StoreService.svc’ye sağ tıklayıp “View in Browser” seçeneğini tıklayarak servise browser üzerinden ulaşabilmekteyiz. Browser, servisi XML formatında bize sunmaktadır.

ProductSet ve CategorySet kolleksiyonlarına özel URI konumlandırıcılar belirlenmiştir. Adres sonuna ProductSet ekleyerek koleksiyon içeriğine de ulaşmak mümkündür.

Bu noktada servisin sunduğu entity tiplerine ait şema bilgisini elde etmekte mümkündür. Bunun için ise URI sonuna /$metadata ekleyerek gerekli metadata bilgisi alınabilmektedir.

Bu yazıda kendi tiplerimize ait kolleksiyonlara ve metadata bilgilerine, WCF Data Servisleri yardımıyla nasıl erişilebileceğini incelemiş olduk. İlerki yazılarda WCF data servislerini daha yakından incelemeye çalışacağız.

WCF Data Services

24 Oca

WCF data servisleri Open Data Protokolünü(OData) kullanarak, WEB veya intranet ortamına Atom ve JSON formatında veri sunabilen servislerdir. OData protokolü URI’ler aracılığıyla adreslenemiş veri kaynaklarına erişmeye olanak sağlar. Bu sayede veri erişimi ve güncelleme işlemleri, standart HTTP işlemleri olan GET, POST, PUT ve DELETE ile yapılabilmektedir.

WCF Data Service Mimarisi

Aşağıdaki şekilde WCF Data Service mimarisi gösterilmektedir.

Şekilde kullanıcı, open data protokolü ve sunucu şeklinde üç ayrı seviye belirlenmiştir.

Kullanıcı tarafı uygulama bağımsızlığına dayanmaktadır. Yani OData protokolü üzerinden gelen verilere herhangi bir platformdan ulaşmak mümkündür.

Sunucu tarafı ise herhangi bir veri kaynağından elde ettiği veriyi OData protokolü üzerinden kullanıcı tarafına sunmaktadır.

WCF data servis mimarisini kısa cümlelerle özetlemeye çalıştık. Bir sonraki yazıda ise WCF data servislerini kullanarak kendi özel kolleksiyonlarımıza nasıl erişebileceğimizi inceleyeceğiz. Hemen ardından gelecek yazıda ise gerçek veritabanına erişebilen EDMX modele ait verilere WCF data servisleri yardımıyla erişmeye çalışacağız.

WordPress otomatik güncelleme uyarısı

23 Oca

WordPress sitesini admin panelinden güncellemek isteyen bütün wordpress sitesi sakinleri güncelleme süresi boyunca “Zamanlanmış bakım dolayısıyla site uygun değil. Bir kaç dakika içinde tekrar kontrol edin.” uyarısını görecektir.

 

Bu uyarıyı gördüğünüzde paniğe kapılmanıza gerek yok. WordPress otomatik olarak kendini bakım moduna almıştır. 5 – 10 dakika süre sonunda güncelleştirmeler biter ve siteniz çalışır hale gelir. Güncelleme dosyalarının indirilme ve güncelleme süresi hosting locasyonu, server internet bağlantı hızına göre değişebilir.

Tekrar görüşmek üzere herkese iyi güncellemeler…

2011 Yılının En Pahalı Bilgisayar Hataları

23 Oca

2012’ya girerken haber ve magazin kanallarında 2011 yılında yaşanana ilginç olayları izledik. Bilgisayar dünyasında yaşanan ve medyada pek yer almayan ancak dolaylı olarak toplumun tümünü ilgilendiren olaylar da olmadı diyemeyiz. Bilgisayarı yöneten ve programlayan da insanlar olduğuna göre hatalar kaçınılmazdır. Yazılım ve bilgisayar ağlarında oluşan insan hatalarının nelere yol açtığını görmek ister misiniz?

Yazılıma ilgi duyan biri olarak son zamanlarda okuduğum ilginç yazılardan birini sizinle paylaşmak istiyorum.

  1. Bir finans firması olan AXA Rosanberg, yatırım modelini oluşturan yazılımdaki bir aksaklık yüzünden 217 milyon dolar kaybetti. Firma müşterilerinden bu durumu gizlese de ABD menkul kıymetler ve borsa komisyonuna 25 milyon dolarlık para cezası ödemek zorunda kaldı.
  2. Bir otomobil üreticisi olan Honda, otomatik vitesi kontrol eden yazılımdaki sorun nedeniyle 2.5 milyon aracı geri çekmek zorunda kaldı. Bu da kötü yazılmış birkaç satır kodun sunucu olarak kayıtlara geçmiş bulunuyor.
  3. Japon bankası Mizuho Financial Group müşterileri ATM ağı ve internet bankacılığı sistemindeki yazılımdan dolayı bir sorunla karşılaştı. Bunun sonucunda 1.5 milyon dolarlık maaş ödemesi gecikti ve 9 milyon dolarlık işemde yapılamadı.
  4. ABD ordusunun, birliklerde veri paylaşımı gibi işlemleri ve ağdaki diğer önemli işlevleri yerine getiren 2.7 milyon dolarlık bulut bilişim ağı çöktü. Bu durumdan dolayı hayatlarının tehlikeye girmesinin yanında para ve zaman kaybının lafı bile edilemez.
  5. Şimdi de müşteriler açıcından cezbedici bir hatayla karşı karşıyayız. Commonwealth Bankasının ATM ağındaki bir oluşan aksaklık, makinelerin rastgele müşteri hesaplarına yüksek miktarlarda para aktarmasına sebep oldu.

Durum böyle olunca aklıma ilk gelen “Böyle bir hataya ben sebebiyet versem ne olurdu?” sorusuydu. Maaştan kesilirdi herhalde 🙂

Kaynak: http://gizmodo.com/5868029/the-worst-computer-bugs-of-2011

C# ile Threading işlemleri

17 Oca

Threading

Threading konusu, yazılım geliştirme sürecinde çok önemli bir kavramdır. Thread’ler sayesinde birçok işi aynı anda eş zamanlı olarak yapmak mümkündür. Yürütülen iş parçacıklarını bir süre bekletmek  veya istenen anda sonlandırmakta mümkündür.

Threading işlemlerini yöneten tipler, .Net Framework tarafında System.Threading alanında barınmaktadır.

Threading konusuna başlamadan önce Thread sınıfını tanımak gerekmektedir. Bu sınıf tek bir iş parçacığı nesnesidir. Yani bir iş parçacığını başlatmayı ve süreci yönetmeyi sağlar.

Bir iş parçacığının oluşturulması şu şekilde olmaktadır.


class SingleThreading
{
  public void StartSingleOperation()
  {
    Thread thread = new Thread(new ThreadStart(work1));
    thread.Start();
  }

  private void work1()
  {
     Console.WriteLine("This is worker thread. ThreadID: {0}",
     Thread.CurrentThread.ManagedThreadId);
  }

}

Burada SingleThreading sınıfı içersinde work1 isimli işi yapan, thread nesnesidir. Yani StartSingleOperation metodu çalıştığında programdaki diğer yürütülen işlemlerin bitmesini beklemeden work1 isimli iş yapılmaya başlanır.

Multiple Thread Kullanımı

Bazı durumlarda birden fazla thread kullanarak iş süreçlerini yönetmek istediğimiz durumlar olabilir. Yani birbirini etkilemeyen, sıra beklemeden eş zamanlı olarak yapılması planlanan süreçleri için aşağıdaki örneği verebiliriz.


class MultipleThreading
{
  public void StartMultipleWriter()
  {

     Thread th1 = new Thread(new ThreadStart(WriteX));
     Thread th2 = new Thread(new ThreadStart(WriteO));

     th1.Start();
     th2.Start();
  }

  private void WriteX()
  {
    for (int i = 0; i < 300; i++)
    {
       Console.Write("X");
    }
  }

  private void WriteO()
  {
     for (int i = 0; i < 300; i++)
     {
       Console.Write("O");
     }
  }

}

Burada th1 ve th1 isimli iki nesne örneği birbirinden bağımsız olarak iki ayrı iş parçacığını yönetmektedir. Burada işlemci iş yoğunluğuna göre eşzamanlama işlemini gerçekleştirmektedir. Yani iki farklı iş bitene kadar biraz WriteX metodundan birazda WriteO metodundan yürütme işlemi yapmaktadır. Bunun ispatı olarak da şu ekran çıktısını verebiliriz.

Görüldüğü gibi bir süre X yazma işlemi yapılmış, bir süre de O yazma işlemi yapılmış. Program her çalıştığında X ve O farklı yerlerde olabilir. Çünkü işlemcinin durumuna göre hangi metodun ne kadar çalışacağı belirlenmektedir.

Önceliklerin belirlenmesi (Thread Priority)

Bazı durumlarda çoklu thread kullanırken öncelik vermek istenen iş parçacıkları olabilir. Birçok thread aynı anda start edildiğinde, bunlardan bir tanesi diğerlerine göre öncelikli olması gerekebilir. Bu gibi durumlarda imdadımıza yetişen Thread.Priority özelliğidir. Bu özellik bir enumerasyon tipindedir. Bu enum tipi, bünyesinde; Highest, AboveNormal, Normal, BelowNormal, Lovest gibi seçenekleri tutmaktadır.

Yukardaki örnekte iş parçacıkları başlatılmadan önce öncelikleri şu kelikde belirleyelim.

public void StartMultipleWriter()
{
   Thread th1 = new Thread(new ThreadStart(WriteX));
   Thread th2 = new Thread(new ThreadStart(WriteO));

   th1.Priority = ThreadPriority.Lowest;
   th2.Priority = ThreadPriority.Highest;

   th1.Start();
   th2.Start();

}

Yani WriteX metodu WriteO metodundan daha az öncelikli olsun. Bu durumda işlemci, WriteO metodunun işlemini daha önce bitirecektir.

Ekran çıktısından da anlaşılacağı gibi WriteX metodu daha az öncelikli olduğundan X yazma işlemi sonlara bırakılmıştır.

Thread.Join metodu ile iş parçacığının bitmesini beklemek

Thread.Join() metodu bir iş parçacığının başka bir göreve başlamadan önce tamamlanması için bekletir. Ayrıca metodun overload edilmiş bir hali ile, belirlenen bir süre kadar işlemin yapılması sağlanır. Belirlenen süre içinde işlem biterse metod geriye True değer döndürür, aksi halde False döndürür.

Örneğin “Thread1” ve “Thread2” adında iki iş parçacığını sırayla çalıştırdığımızı varsayalım. “Thread1” çalışırken ”Thread2.Join()” metodunu çağırdığımızda “Thread2” işlemini bitirene kadar “Thread1” bekler. Ardından “Thread1” işlemine devam eder. Eğer ”Thread2.Join(int)” metodu çağırıldğında ise, belirlenen süre içinde işlem bitmezsse bekleyen diğer iş parçacığı çalışmaya başlar.

Bu yazımızda threading işlemlerinden  bahsetmiş olduk. Umarım faydalı bir yazı olmuştur.