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.