Prism ile Silverlight MVVM ve Modüler Programlamaya Giriş

24 Eyl

Bir önceki yazımızda Silverlight MVVM yazılım tasarımı konusuna giriş yapmıştık ve anlaşılabilir olması açısından giriş seviyede bir örnek uygulama yaparak konuyu pekiştirmeye çalışmıştık. Bu yazımızda da Prism kütüphanelerini kullanarak modüler yapıda basit bir uygulama geliştirmeye çalışacağız. Bir önceki örnek MVVM uygulamızda Product model üzerinden View ve ViewModel yapılarını oluşturmuştuk. Bu yazıdaki uygulamada ise Product model ve View tarafını ayrı bir silverlight projesinde barındırıp ana silverlight projesi üzerine modül şeklinde ekleyeceğiz.

Bir önceki örnek uygulamadaki Model, View ve ViewModel yapılarını ProductModule adında ayrı bir silverlight uygulamasına çektik. Solution içerisindeki BasicModularity bizim ana silverlight uygulamamız. Yani ProductModule uygulaması, BasicModularity uygulaması üzerinde çalışacak ve BasicModularity.Web tarafından web yayınına sunulacak.

ProductModule uygulamasının bir modül olarak kabul edilebilmesi için IModule interface tipini implemente eden bir sınıfa sahip olması gerekmektedir. IModule interface tipi ise Microsoft.Practices.Prism.Modularity altında bulunmaktadır. ProductModule projesini modül halie getiren ise ProductModul sınıfıdır. Bu sınıfın içeriği aşağıdaki gibidir.


public class ProductModul : IModule
{
     private readonly IRegionManager manager;

     public ProductModul(IRegionManager manager)
     {
         this.manager = manager;
     }

     public void Initialize()
     {
         manager.RegisterViewWithRegion("ProductSaveRegion", typeof(Views.ProductView));
     }

}

IModule interface içerisinde Initialize adında bir metod bulunmaktadır. Bu metod modülün başlatılmasını sağlamaktadır. IRegionManager interface tipi ise modülün ana uygulamada hangi bölgeye yerleşeceğini belirleyen bir tiptir. Biz bu uygulamada modüldeki ProductView görüntüsünün ProductSaveRegion adındaki bir bölgede tutulmasını istedik. Biraz sonra bu bölgeyi ana uygulamada bir ItemControl belirleyeceğiz.

BasicModularity uygulaması yani ana uygulamamız tarafında modülleri barındıracak şekilde bir takım hazırlıklar yapmamız gerekmektedir.

Öncelikle Shell.xaml user kontrolü ekleyerek modülündeki ProductView için bir bölge(region) oluşturmalıyız.

ProductModule içerisinde işaret edilen bölgeyi oluturduk.

Artık modüllerin ana çatı tarafından tanınması ve yüklenmesi için gerekli olan başlangıç mekanizmasını oluşturmanın vakti geldi. Bu mekanizmanın ana sınıfı UnityBootstrapper denen tiptir. Bu tipten türeterek oluşturduğumuz sınıfımızın adı MainBootstrapper. Sınıfımızın içeriği aşağıdaki gibidir.


public class MainBootstrapper:UnityBootstrapper
{
    protected override DependencyObject CreateShell()
    {
        return Container.Resolve<Shell>();
    }

    protected override void InitializeShell()
    {
        Shell shell =new Shell();
        Application.Current.RootVisual = shell;
    }

    protected override IModuleCatalog CreateModuleCatalog()
    {
        ModuleCatalog catalog = new ModuleCatalog();
        catalog.AddModule(typeof(ProductModule.ProductModul));
        return catalog;
    }

}

CreateShell metodu ana yapı olan Shell tipinden bir nesneye işaret etmektedir.

InitializeShell ise Application.Current.RootVisual UIElementine Shell nesnesini göstermektedir.

CreateModuleCatalog ise yüklenecek olan modllüeri göstermektedir.

App.xaml.cs içerisindeki Application_Startup metodunda ise MainBootstrapper başlatılmaktadır.


private void Application_Startup(object sender, StartupEventArgs e)
{

    MainBootstrapper boot=new MainBootstrapper();
    boot.Run();

}

Uygulamamız artık çalıştırılmaya hazır.

Bu yazımızda Pism ile ilgili detaylı bilgiler vermedim. Daha sonraki yazılarda kısmetse Prism nedir ne değildir şeklinde bir yazı hazırlayabilirim.

Tekrar görüşmek ümidiyle.

Örnek Uygulama Kodlarına Buradan Erişebilirsiniz.

Kaynakhttp://compositewpf.codeplex.com/

Silverlight MVVM Giriş ve Prism DelegateCommand

21 Eyl

Web projelerini ASP.NET MVC ile geliştirenlerden olduğum için Silverlight tarafında da kendi çabalarımla model view tarzı çalışmalarla uğraşmaktaydım. Silverlight tarafında da katmanları birbirinden izole eden böyle bir yapı var mı diye araştırırken MVVM(Model View and ViewModel) yazılım tasarımıyla karşılaştım.

Yazılım tasarımları yeni başlayanlar için pek bir şey ifade etmeyebilir. Fakat uzman yazılımcılığa adım attıktan sonra, geleneksel yöntemlerle işlerin çorbaya dönüştüğü ve içinden çıkılamaz bir hale geldiğini görenler çıkış noktası aramaya başlarlar. Böylece ilk başlarda saçma gelen yöntemler artık yazılımcı için tam anlamıyla can simidi olur. Bu yazımızda da Silverlight MVVM yazılım tasarımını, giriş seviyesindeki bir örnekle incelemeye çalışacağız.

MVVM yazılım tasarımındaki temel amaçlar:

  • Yazılımda esnekliğin sağlanması(Loosely Coupled),
  • Genişletilebilir bir yazılım oluşturulabilmesi(Open Closed),
  • Test edilebilir yazılımın oluşturulabilmesi,
  • Kod tekrarlarının önune geçilmesi (Clean Code) şeklinde sıralanabilir.

MVVM sayesinde Silverlight framework elementlerin(xaml tarfının) ve CLR (C#, VB gibi) kodlama tarafının birbirinden yalıtımı da sağlanabilir. Xaml ve Kod tarafında event paslaşmalarını Command Binding mekanizmalarıyla ortadan kaldırmak MVVM tasarımında işleri daha da kolaylaştırmaktadır.

Microsoft Pattern & Practices ürünlerinden olan Prism kütüphanesi sayesinde Desktop uygulamaları ve Silverlight uygulamalarında modülerliği ve yazılımda esnekliği sağlayan bir takım özellikler mevcuttur. Bu yazımızdaki örnek uygulamada command binding diye adlandırılan yapıdan bahsedeceğiz.

ViewModel içerisine tanımlanan bir ICommand nesnesi aracılığı ile View tarafından commanding işlemi gereçekleştirilebilmektedir. Tekrardan view tarafında tanımlanan button v.s gibi bileşenlerin event’lerini yakalayıp, iş operasyonlarını gerçekleştiren süreçleri view tarafına sokmamış oluruz. Yani kısaca herkes kendi yoluna gider.

Şimdi giriş seviyesinde bir örnek uygulama yaparak konuyu incelemeye başlayabiliriz. Örneğimize başlamadan önce Microsoft Pattern & Practices sitesinden Prism kütüphanelerini indirip bunlardan Microsoft.Practices.Prism referans olarak projemize eklemek gerekmektedir.

Örnek Uygulama

Örnek senayyomuz, bir Product tipinin arayüz ayrımının yapılması şeklinde olacaktır.

Model olarak Product adında basit bir temel tip belirliyoruz.


public class Product
{
    public string Name { get; set; }
    public decimal Price { get; set; }
    public override string ToString()
    {
         return string.Format("Name: {0}, Price: {1}", Name, Price);
    }

}

Bu tipimizi görünüm arayüzünde (xaml tarfına) temsil edecek bir tip oluşturmamız gerekiyor. Bu tip aslında bizim ViewModel dediğimiz yapıyı oluşturacak olan tiptir.


public class ProductViewModel
{
    private readonly Product product;
    public ICommand SaveCommand { get; set; }
    public Product Product { get { return product; } }

    public ProductViewModel()
    {
        product = new Product {Name = "Notebook", Price = 1500};
        SaveCommand = new DelegateCommand<object>(OnSave);
    }

    private void OnSave(object obj)
    {
        MessageBox.Show(product.ToString());
    }

}

Yukarıda görüldüğü gibi ViewModel tipimizin adı ProductViewModel şeklindedir. Bu tip, içerisinde Product tipini barındırıyor ve kaydetme işlemini tetikleyecek olan ICommand tipinde bir nesne barındırıyor. Constructor içerisinde ürün bilgileri ve Command işlemini yapacak olan nesnenin oluşturulma işlemi gerçekleştiriliyor. DelegateCommad tipi, Microsoft.Practices.Prism.Commands

İçerisinde bulunmaktadır. Bizim senaryomuzda herhangi bir kayıt söz konusu olmadığından kaydetme işlemini MessageBox mesajı ile geçiştiriyoruz.

View tarafında da kayıt bilgilerinin alındığı bir form tasarımı oluşturacağız. Ayrıca View tarafında DataContext olarak az önce oluşturduğumuz ViewModel tipini göstereceğiz. View kontrolümüz ProductView.xaml şeklindedir ve içeriği aşağıdaki gibidir. Cs kod tarafında hiç bir işlem yapılmamıştır.

Hazırlık aşaması tamam olduğuna göre artık oluşturduğumuz View, Mainpage.xaml içerisine yerleştirilebilir.

Burada dikkat etmemiz gereken noktalardan biri, button click event’ine hiç kod yazılmaması. Bunun yerinde Command mekanizmasının kullanılmasıdır. Command binding, MVVM tasarım desenini kullanmayı kolaylaştıran yöntemlerden biridir. Eğer button click event kullanılsaydı View tarafında View tarafında yapılmaması gereken bir işlem yapılmış olacaktı.

Sonuç olarak Solution penceremiz şu şekildedir. Klasörleri kendim oluşturdum, yani visual studio tarafından hazır olarak sunulan bir MVVM projesi yok.

Tekrar görüşmek ümidiyle.

Örnek Uygulama Kodlarına Buradan Erişebilirsiniz.

Silverlight Commanding Kavramı

20 Eyl

Silverlight tarafında çalışma zamanında(runtime) yapılmasına gerek duyulan implementasyonlar yüzünden MVVM gibi yazılım tasarımlar gün yüzüne çıkmıştır. Bu tarz kod yazım tasarımları, ürünlere bağlı değildir aslında. Ancak ürün sahipleri, yeni sürümlerini çıkarırken, geliştiricilere yardımcı olabilmek ve güncelliği korumak adına bir dizi eklemeler yapabilmektedirler. Silverlight tarafında  Silverlight 4 ile birlikte gelen Commanding yapısı da bize kolaylık sağlayacak özelliklerden biridir.

Commading yapısının bize sağlayacağı kolaylıkların başında, event ve eventhandler mekanizmalarıyla uğraşmadan kod akışını düzenlemek geliyor. Yani normal kodlama yaparken alışkanlıklarımızdan biri şudur: arayüz(xaml) tarafındaki bir bileşende gerçekleşecek olan bir olay aynı xaml dosyasına bağlı *.cs kod dosyasında yaparız. Commanding yapısında ise gerçekleşen olayı ayrı bir sınıf aracılığıyla yaparız. Diğer bir husus ise modüler programlama yaparken sağlayacağı kolaylıktır ki bizi en çok rahatlatacak olan özelliklerinden biri de budur. Bir modül oluşturduğunuzu düşünün(ayrı bir silverlight dll). Bu modül üzerinde görsellikle diğer katmanlar rahatlıkla ayrılabilir.

En basit şekliyle event yakalama işlemini gösteren bir uygulamayla işe başlayalım.

Örnek Uygulama

Bu örneğimizde bir butona tıkladığımızda verilen mesajı hem cs kodundaki event ile hem de command mekanizmasıyla gerçekleştireceğiz.


private void button1_Click(object sender, RoutedEventArgs e)
{
      MessageBox.Show("Mainpage.cs tarafındaki event");
}

Yukarıdaki kod ile alışılagelmiş ve en basit haliyle butona tıklayıp sonuç alma işlemini gerçekleştirmiş olduk. Bu işlemi bir de comman binding yardımıyla ile yapalım.

public class MessageCommand:ICommand
{
     public bool CanExecute(object parameter)
     {
        return true;
     }
     public void Execute(object parameter)
     {
         MessageBox.Show("MessageCommand tarafından gelen event.");
     }

     public event EventHandler CanExecuteChanged;
}

Öncelikle ICommand arayüzünü uygulayan MessageCommand bir sınıf oluşturduk. Bu sınıf, ICommand ile gelen CanExecute, Execute, CanexecuteChanged üyelerini de barındırıyor.

Belirtmekte fayda var. ICommand arayüzünün profili de şu şeklidedir.

public interface ICommand
{
       event EventHandler CanExecuteChanged;
       bool CanExecute(object parameter);
       void Execute(object parameter);

}

Şimdi xaml tarafında MessageCommand tipine butonu bağlayabiliriz.

Bu uygulama, command binding işleminin nasıl yapıldığını en düşük seviyede anlatan bir uygulamadır. İleri seviyedeki uygulamalar ise MVVM(Model View and ViewModel) tasarım deseni uygulandığı örneklerde gösterilmektedir. önümüzdeki yazılarda bu konuya değinmeye çalışacağız.

Tekrar görüşmek ümidiyle.

Blog yazma amacım

19 Eyl

Bu blog sayfasını yazma amacım bilgi paylaşımı yapmak olup yazılım dünyasına az da olsa fayda sunabilmektir. Amacım arama motorlarında ön sıralarda çıkıp kullanıcıya hiçbir katkı sağlamayan ve sadece zaman kaybettiren bir web içeriği sunmak değildir. Amacım arama motorlarında aradığı başlığı bulan kullanıcıya aradığı şeyi sunmuş olabilmek ve eğer lütfeder ise bir teşekkürünü alabilmektir. Kafamda birçok konuyla ilgili ufakta olsa yazıya dökülebilecek bilgiler var. Ancak bunları eksik şekilde yazmak, okuyucuya bir fayda sunmayacağı gibi okuyucunun vaktini boşa harcamasına sebep olacaktır. Bu nedenle yazıya dökmediğim birçok konu da mevcuttur. Aynı hassasiyeti boş yazılarla vaktimizi çalan blog yazarlarından da bekliyorum.  İnternette var olan konulara farklı yönlerden yaklaşabilir, farklı örnekler vererek konuları anlaşılır bir biçimde sunabiliriz. Ancak eksik ve yanlış bilgiler sunmak mesleğimize yapılmış bir saygısızlıktır.

Yapay yöntemlerle arama motorlarını kandıran ve bu uğurda gerçek bilgiyi sunan sitelerin haklarını sömüren internet siteleri sahiplerine ve kendini Hacker zannedenlere duyurulur.

Windows mu Linux mu?

17 Eyl

İşletim sistemlerine karşı fanatizm boyutunda bir taraf tutma savaşı vardır. Linux taraftarları ve Windows taraftarları topluluklarda ve sosyal medyada kısır tartışma içerisindedir genelde. Bu tür tartışmalara girmeden önce, işletim sistemlerinin neyi hedeflediğini bilmemiz gerekmektedir. Amacımıza uygun işletim sistemini seçebiliyor muyuz diye bir bakmamız gerekir ilk önce. Fakat amaca uygun işletim sistemi nasıl seçilir? Hangi tarafta durmamız gerektiğini nasıl belirlemeliyiz?

Microsoft firmasının Windows işletim sistemini çıkarma amacı ve inancı, gelecekte her evde bir kişisel bilgisayar olmasıydı. Her evde bir bilgisayarın olması demek bir de işletim sisteminin olması demektir. Windows işletim siteminin ev kullanıcılarına dönük yani profesyonellik istemeyen bir ilkesi vardır. Yani herkesin kullanabileceği bir işletim sistemidir Windows. Amacına uygun şekilde yapılmış mı? Bence evet. Öyle olmasaydı çoğunluk Windows işletim sistemini kullanmazdı. Çoğunluğun Windows kullanması belki başka seçeneğin olmamasından kaynaklanıyor diye akıllara gelebilir ama günümüzde başka işletim sistemlerinin de olması Windows işletim sistemini kenara attıramamıştır.

Gelelim Linux tarafına. Linux işletim sistemi, ev kullanıcısından ziyade daha profesyonel kullanıcılara hitap eden bir işletim sistemidir. Linux, kullanıcıya her şeyi hazır olarak sunmaz. Daha fazla bilgi ve emek ister. Programlar kapalı kutular şeklinde değil açık kaynak şeklindedir. Bilgili ve profesyonel olmadan her şey açık kaynak, her şey özgür sloganlarıyla Linux kullanmaya kalkan acemi kullanıcılar, bir ekran kartı sürücüsünü 1 günde yükleyemeyince hayal kırıklığı yaşayabiliyor.

Profesyonel olmak kişinin özgür seçimidir. Bilgisayar sistemleri konusunda belli bir noktaya gelenler ve işletim sistemi çekirdeği seviyesinde çalışma becerisine sahip olan kullanıcılar gayet tabi Linux işletim sistemini seçebilir. Bilgisayar mühendisleri, gömülü istemlere yazılım üretenler için açık kaynak ve Linux biçilmiş kaftandır diyebilirim. Ancak ev kullanıcıları, işletim sistemi seviyesinde çalışacak yazılımlar üretmek isteyenler ve kolayca yazılım üretip kullanmak isteyenler için de Windows kullanmak avantajlı olur diyebilirim.

Linux tarafında duranlar da genelde önce Windows işletim sistemini kullanıp sonra Linux tarafına geçenlerdir. Kabul etmeliyiz ki Windows işletim sistemi olmasaydı çoğumuz bilgisayar sistemlerini geç tanırdık ve birçok kullanıcı da hala bilgisayar kullanamıyor olurdu. Bilgisayarlar şirketlere ve geliri üst seviyede olan insanlara has ürünler olurdu. Ev kullanıcısına ulaşması çok daha uzun seneler alabilirdi. Bu nokta da insanlığı Windows işletim sistemiyle tanıştıran Microsoft firmasının hakkını yememek gerek.

Şeçim sizin…

Chain Constructors Refactoring C#

10 Eyl

Bir sınıfın birden fazla kurucu metodu (constructor) varsa, kod tekrarları da oluşacak demektir. Çünkü kurucu metodların fazla olması, parametrelerin fazla olmasını gerektirir. Dolayısıyla sınıfın üyelerinin tekrarlı bir şeklide atama işlemine tabi tutulması demektir. Bu kod tekrarlarının nasıl oluştuğunu şu örnekle inceleyebiliriz.


public class PersonManager
{
      private string firstName;
      private string lastName;
      private string socialSecurityNumber;
      private string age;

      public PersonManager(string firstName, string lastName)
      {
          this.firstName = firstName;
          this.lastName = lastName;
      }

      public PersonManager(string firstName, string lastName, string socialSecurityNumber)
      {
          this.firstName = firstName;
          this.lastName = lastName;
          this.socialSecurityNumber = socialSecurityNumber;
      }

      public PersonManager(string firstName, string lastName,string age, string socialSecurityNumber)
      {
          this.firstName = firstName;
          this.lastName = lastName;
          this.age = age;
          this.socialSecurityNumber = socialSecurityNumber;
      }

}

Private erişimli field’lar her kurucu metodda tekrarlı bir şekilde işleme sokulmuş. Bunun önüne şu şeklide geçmek mümkündür.


public PersonManager(string firstName, string lastName)
      :this(firstName,lastName,"Unknown", "Unknown")
{
}

public PersonManager(string firstName, string lastName, string socialSecurityNumber)
       : this(firstName, lastName, socialSecurityNumber, "Unknown")
{
}

public PersonManager(string firstName, string lastName, string socialSecurityNumber, string age)
{
       this.firstName = firstName;
       this.lastName = lastName;
       this.age = age;
       this.socialSecurityNumber = socialSecurityNumber;
}

Bu şekilde kodumuzu tekrarlı yapıdan arındırdık.

Tekrar görüşmek üzere.

Kitap – Programming WCF Services 3rd Edition

8 Eyl

Okuyucuyu,  WCF (windows comminication foundation) dünyasının derinliklerinde gezintiye çıkaran bir kitap. Kitabın kapağındaki balığın sebebi de bu dur belkide. Derinlerde gezen bir balık. O’Relly yayınlarının birçok kitabının kapağında ayrı bir hayvan resmi kullanılır. Kapaklarda kullanılan hayvanların listesini merak ederseniz buradan ulaşabilirsiniz.

Bu kitapta WCF mimarisi derinlemesine anlatılmaktadır. Yaklaşık 900 sayfalık bir kitap olması, ne kadar ince detaylara indiği konusunda fikir verebilir.

Kitabı, amazon.com üzerinden satın alabilirsiniz.

Eğer WCF servisleri konusunda, sıfırdan uygulamalar geliştiren bir kitap arıyorsanız, bu kitap size göre değil. Ama WCF servislerini öğrenmeye başladınız ve neyi neden yaptığınızı merak ediyorsanız bu kitap tam size göre. Kulandığınız her nesnenin ne işe yaradığını ve nasıl kullanıldığı anlatılmış, örnek kod parçaları ile güçlendirilmiştir.

Okumaktan zevk aldığım bir kitap. Umarım siz de zevkle okursunuz.

Koşullu Mantığın Komutla Değiştirilmesi (Replace Conditional Dispatcher with Command)

5 Eyl

Programcıların öğrenme aşamasındaki alışkanlıklarından dolayı olsa gerek, koşullu mantığın kullanılması hat safhadadır. Olay Nesneye Dayalı programlamaya gelince, koşullu mantık bir takım değişikliklere uğrayabiliyor. Bu değişiklikler, aslında olması gereken değişikliklerdir. Bu değişikliklerle çoğu zaman karmaşık kod yapılarından kurtuluruz. Nasıl mı?


public class PersonManager
{
     public double GetHourlyRate(Person person)
     {
         if (person is Employee)
             return 2.0;
         if (person is Student)
             return 1.0;
         return 0.0;
     }
}

Yukarıda tanımlı GetHourlyRate metodu içerisinde person tipinin Employee veya Student olup olmadığı kontrol ediliyor. Bir süre sonra sisteme yeni bir tip eklendiğinde GetHourlyRate metodunda bir koşul daha eklenerek değişiklikler gerekecek. Bu iyi bir yöntem değil. Zaten Open Closed tasarım ilkesine de uymayan bir durum. Bu durumu değiştirelim.


public class PersonManager
{
       public double GetHourlyRate(Person person)
       {
           return person.GetRate();
       }
}

public class Person
{
     public virtual double GetRate()
     {
         return 0.0;
     }
}

public class Student:Person
{
     public override double GetRate()
     {
         return 1.0;
     }
}

public class Employee:Person
{
      public override double GetRate()
      {
         return 2.0;
      }
}

GetHourlyRate metodunda Person nesnesinin bir komutu olan GetRate kullanılıyor. Bu durumda sisteme istediğimiz kadar yeni tip ekleyebiliriz. Çünkü artık gelişime açık bir kod ortaya koyduk. Open Closed ilkesine uyduk.

Tekrar görüşmek dileğiyle.