10 Haziran 2010 Perşembe

WCF Ria 3 - Veri Erisimi

Tüm iş uygulamaları veri ile ilgilenirler. Şimdi Ria Servis uygulamasında veri işlemlerinin nasıl yapıldığını inceleyeceğiz. Yeni bir Ria uygulaması açalım. Ben bu uygulamada Linq to SQL kullanacağım. Ria servis Entity Framework veri modeli, xml dosyalar, web servisleri gibi veri kaynakları ile sorunsuz çalışmaktadır. Veri yapımızı oluşturalım.

Sorumuz şu silverlight istemcisi üzerinden veriye nasıl ulaşacağız? Geliştiriciler veri iletişiminde çok katmanlı mimari yapısına güvenmektedir. WCF ve ADO.NET Data servislerini kullanan NET Ria servisleri ile çok katmanlı uygulamalar kolaylıkla kurulabilmektedir.

Yukarıda Ria Servis uygulama mimarisi görülmektedir. Burada ön yüz, uygulama mantığı ve veriyi saklayacak çeşitli kaynaklar bulunmaktadır. En önemli kazançlardan bir tanesi veri kaynağı olarak tercihlerinizi ön yüzde değişiklik yapmadan değiştirebilmenizdir.

Ria Servismizi oluşturalım. Sunucu projemize sağ tıklayalım ve yeni bir “Domain Service” sınıfı oluşturalım.

Ekledikten sonra bizi bir sihirbaz karşılayacak ve bizden veri kaynağını seçmemiz bekleyecek.

AdventureWorksDomainService.cs sınıfında sizin verilerine ulaşmak kullanabileceğiniz tüm CRUD metot taslakları var. Tabiki bu metotları kendi etki alanıza (Domain) göre özelleştirebilirsiniz. Şimdi gidip GetEmpployess() metodunu biraz özelleştirelim.

[cs]

public IQueryable GetEmployees()
        {
            return this.DataContext.Employees
                .Where(r=>r.SalariedFlag == true)
                .OrderBy( r=>r.Title)
                .ThenBy(r=>r.BirthDate);
        }

İstemci tarafa geçelim. İstemcinin sunucu üzerinde ki bu servise erişebilmesi için uygulamayı built edelim. Sunucu projesi istemci projeye bağlanmıştır çünkü servisi oluştururken seçtiğimiz “Enable client access” özelliği ASP.NET erişimine açık bir servis oluşturur ve bu servise ait Proxy sınıfını istemci tarafında üretir. 

Şimdi önyüzü hazırlayalım. Data -> Show Data Sources menüsü ile veri kaynakları panelini açalım.  Burada iki veri kaynağı göreceksiniz. Birisini Ria servis tarafından standart olarak sunulan ve kullanıcı ekleme işlemi için kullanılan UserRegistrationContext. Diğer veri kaynağı bir önceki adımda oluşturduğumuz AdventureWorksDomainContext. AdventureWorksDomainContext Employee tablosunu göreceksiniz. Employee tablosuna tıkladığınızda bu tablonun GetEmployeesQuery fonksiyonu ile üretildiğini görüyoruz. Eğer Employee tablosunu üreten birden fazla fonksiyon olsa idi bu menüden seçebilecektik. Aynı menüde tablonun form üzerine hangi bileşen ile gösterileceğini seçebiliyoruz. Tabloları DataGrid, ListBox veya Details olarak gösterebiliyoruz. Aynı menüden veri form üzerinden göstermek için kullanılabilecek yeni bir bileşende seçebiliriz.

Employee tablosu için DataGrid gösterimini seçelim daha sonra Employee tablosunu form üzerine sürükleyelim. Visual Studio bizim için Employee tablosunu ait bir grid ve gridin veri kaynağını oluşturacaktır.

Oluşan kodları inceleyelim.

<riaControls:DomainDataSource AutoLoad="True" Height="0" Width="0"   
    Name="employeeDomainDataSource" QueryName="GetEmployeesQuery" >
     <riaControls:DomainDataSource.DomainContext>
           <my:AdventureWorksDomainContext />
      </riaControls:DomainDataSource.DomainContext>
<sdk:DataGrid AutoGenerateColumns="False" Height="200"
    ItemsSource="{Binding ElementName=employeeDomainDataSource, Path=Data}"
    Name="employeeDataGrid"
    RowDetailsVisibilityMode="VisibleWhenSelected" Width="400">

Veri kaynağı olarak riaControls altında ki DomainDataSource nesnesinin kullanıldığını görüyoruz. Veri erişim fonksiyonu olarak da AdventureWorksDomainContext sınıfı altında ki GetEmployessQuery metodunu kullandığını görüyoruz. AdventureWorksDomainContext sınıfı nerede?

Web projesi içinde yazdığımız Domain Service sınıfımız Proxy nesnesi Silverlight uygulamamızın Generated_Code dizini içine kod üretimi ile yerleştirilmiştir. Uygulamayı deneyelim şimdi.

Çok fazla kayıtın gride dolduğunu görüyoruz. Sayfalama özelliği eklemek için forma bir DataPager ekleyelim. Eklediğimiz DataPager veri kaynağını ayarlamak için Data Sources alanında ki Employee tablosunu sürükleyip DataPager bileşenine bırakabiliriz.

<riaControls:DomainDataSource AutoLoad="True"
    Name="employeeDomainDataSource"
    QueryName="GetEmployeesQuery" LoadSize="20">
    <riaControls:DomainDataSource.DomainContext>
                        <my:AdventureWorksDomainContext />
                    </riaControls:DomainDataSource.DomainContext>
                </riaControls:DomainDataSource>
<sdk:DataPager Name="dataPager1" PageSize="10"
    Source="{Binding ElementName=employeeDomainDataSource, Path=Data}" />

Böylelikle her sayfada on kayıt gösterilecek ve sunucudan her seferinde yirmi kayıt çekilecektir. Bir seferde yirmi kayıt yüklenirken sadece on tanesi gösterilecektir. Dolayısı ile ikinci sayfaya geçince istemci veri yüklemek için sunucuya gitmeyecektir. Üçüncü sayfaya geçerken sonra ki yirmi kayıt istemciye yüklenecektir. Böylece tüm kayıtlar yerine gereken kayıtlar istemciye taşınacaktır.

Grid üzerine Title kolonuna göre bir gruplama ekleyelim.

<riaControls:DomainDataSource.GroupDescriptors>
     <riaControls:GroupDescriptor PropertyPath="Title"/>
</riaControls:DomainDataSource.GroupDescriptors>

Filtreleme ekleyelim. Bunun için filtre bilgisinin girileceği bir TextBox   ihtiyacımız var.

  <StackPanel Orientation="Horizontal" >
    <TextBlock Text="National ID: "></TextBlock>
    <TextBox x:Name="txtNationalID" Width="150" Height="25"></TextBox>
  </StackPanel>

Veri kaynağımıza nasıl filtre yapması gerektiğini söyleyelim.

<riaControls:DomainDataSource.FilterDescriptors >
   <riaControls:FilterDescriptor Operator="StartsWith"
    PropertyPath="NationalIDNumber"
    Value="{Binding ElementName=txtNationalID, Path=Text}"/>
</riaControls:DomainDataSource.FilterDescriptors>

Şimdi bu işlemlerin nasıl çalıştığını inceleyelim. AdventureWorksDomainService.GetEmployees fonksiyonuna bir break point ekleyelim. Projeyi çalıştırıp yeni bir filtre değeri girelim.  Inttelli Trace penceresinde yapılan tüm işlemleri görebilirsiniz.

Yukarda görüldüğü gibi girdiğimiz filtre değeri girildiği anda Ria Domain Data Source nesnesi ilk olarak web servis çağrısı yapmaktadır.

Bu web çağrısından sonra istenen veri kümesinde yer alan toplam kayıt sayısı bulunmuş. Toplam kayıt sayısı bulunurken bizim ön yüzden girdiğimiz filtre değeri ve AdventureWorksDomainService.GetEmployees fonksiyonu içinde belirttiğimiz Where koşul ve Order By koşullarınında çalışan Query içine eklendiğini görüyoruz. Böylelikle Query’inler dinamik olarak orta seviyede hem web hem ön yüz tarafının ihtiyaçlarına göre üretildiğini görüyoruz.

Son olarak kullanılacak verinin çekildiğini görüyoruz. En son olarak da üretilen verinin istemciye gönderildiğini görüyoruz.

Tüm bu işlemleri biz sadece Ria araçlarını kullanarak oluşturduk. Ria Domain Data Source gerekli noktalarda web tarafına giderek gereken Query’leri çalıştırmadadır. Böylece biz sadece işin kurallarına eğilip gereksiz kodlamalardan uzak durmuş olmaktayız.

Ria servisleri ile veri erişimi erişimini ve veri gösterimini örneklemiş olduk. Şimdi Ria servisleri ile veri ekleme/değiştirme ve silme olaylarını inceleyelim. Veri güncelleme işlemi içinde Ria servis araçlarından faydalanacağız.  Formumuza Silverlight Toolkit içinde yer alan bir DataForm ekleyelim.

<sdk:DataGrid AutoGenerateColumns="True" Grid.Column="0"
    ItemsSource="{Binding ElementName=employeeDomainDataSource, Path=Data}"
    Name="employeeDataGrid"   
    MinHeight="300" MaxHeight="300"/>
<sdk:DataPager Name="dataPager1" PageSize="10" Grid.Column="0"
    Source="{Binding ElementName=employeeDomainDataSource, Path=Data}"  />
<dataForm:DataForm Grid.Column="1"
    CommandButtonsVisibility="All"
    ItemsSource="{Binding ElementName=employeeDomainDataSource, Path=DataView}"/>

DataForm bileşeni ile Ria Domain Data Context üzerinde ki kayıtları manipüle edebilirsiniz. Değişen kayıtlar için yukarıda görüldüğü gibi sol üst köşede bir yıldız belirir. Bu yıldızın sizin istemci üzerinde yaptığınız değişiklikler henüz sunucuya gönderilmediğini gösterir. Form üzerine bir buton ekleyip değişiklikleri sunucuya Ria Domain Data Context üzerinde ki değişiklileri sunucuya gönderelim.

[cs]

private void btnSave_Click(object sender, System.Windows.RoutedEventArgs e)
{
 dataForm1.CommitEdit();
 employeeDomainDataSource.SubmitChanges();
}

Böylece Silverlight tarafında bulunan Ria Domain Data Context sınıfı kendi üzerinde tüm değişiklikleri Web tarafında ki Ria Domain Servise iletmekte ve daha sonra Domain Servisin değişikleri veri tabanına yazılmasını sağlamaktadır. Bizim ön yüzde yaptığımız tüm değişiklikler SubmitChanges() metodu çağrılana kadar ön yüzde beklemektedir. Domain Data Context SubmitCahnges() metotunun çağrılması ile ilgili Domain Servis içinde ki gerekli Insert, Update ve Delete metotları tek tek çağırılacak ve tüm değişiklik kümesi sunucuya iletildikten sonra Domain Servis üzerinde Submit metodu çağrılacaktır. Web tarafında tüm işlemleri bir transaction içine alalım ve değişiklikleri bu şekilde geçmesini sağlayalım.

[cs]

public class AdventureWorksDomainService : LinqToSqlDomainService
{
 public override bool Submit(System.ServiceModel.DomainServices.Server.ChangeSet changeSet) 
 {
  try
  { 
   using (TransactionScope scope = 
    new TransactionScope(TransactionScopeOption.RequiresNew))
   {  
    base.Submit(changeSet);  
    scope.Complete();  
    return true; 
   } 
  }catch { } 
  return false;
        }
}

Şimdide CRUD işlemlerinin nasıl yapıldığını inceleyelim.

Yukarıda da görüldüğü gibi Ria Domain Servis bizim için gerekli Insert/Update/Delete Query’lerini oluşturdu ve kayıt işlemlerimizi yaptı.

Tüm süreci özetleyelim. Veri erişimimizi sağlayacak yöntemi seçtik. Bu uygulamada birçok alternatif arasından Linq To SQL uyguladık. Daha sonra Domain Servisini oluşturduk ve standart veri erişim metotlarımız geldi. Domain Servis sınıfımız Silverlight istemci uygulamamızdan çağırabileceğimiz Domain Context sınıfımız Ria tarafından otomatik olarak oluşturuldu. Ria bileşenlerinin gerekli veri sorgulamaları otomatik olarak yapabildiklerini gördük. Tüm bu işlemleride Ria Domain Servis gerekli Query’leri bizim yerimize oluşturdu.

9 Haziran 2010 Çarşamba

WCF Ria 2- Ön yüz ve Şablonlar

Bir iş uygulaması profesyonel duruşa sahip olmalıdır. Fakat bu görünümü verecek bir tasarımcıya her zaman sahip olamayabilirsiniz. Ria uygulama şablonu temiz anlaşılır uygulama yapısı ve kolaylıkla değiştirilebilen güzel bir ön yüz ile gelmektedir.

Öncelikle Silverlight Ria uygulaması sayfalar arasında ileri geri gezinmeye izin veren bir konumlanma desteğine sahiptir.

Uygulama adres satının da ki url bilgisi kopyala-yapıştır yapılabilmektedir.Böylelikle url’lerinizi paylaşabilirsiniz.


Silverlight Ria uygulaması uygulama içinde oluşan hataları çok kalay bir şekilde yönetmekte ve göze hoş gelen bir şekilde göstermektedir. Aşağıda yanlış link hatası gösterilmiştir.

Şimdi uygulamanın Views dizini altılana yeni bir Silverlight sayfası ekleyelim.

Açılan sayfanı içine bir şeyler ekleyelim. Şimdi uygulamanın menüsüne bu sayfa ait bir link ekleyelim. Link eklemek için MainPage.xmal içine mevcut linkler ile aynı formatta yeni bir bağlantı ekleyelim.

<Rectangle Style="{StaticResource DividerStyle}"/>                        
    <HyperlinkButton Style="{StaticResource LinkStyle}"                  
        NavigateUri="/Page1"                  
        TargetName="ContentFrame"                  
        Content="sayfa 1"/>

Uygulamayı bize özel yapmak için uygulama adını değiştirelim. Bunun için Assets\Resources atında ki ApplicationStrings kaynak dosyasında “Application Name” olan uygulama adını istediğimiz gibi değiştirelim.

Şimdide uygulamanın renk ayarlarını kendi istediğimiz şekilde değiştirelim. Assets dizininde ki Styles.xmal dosyasını açalım. Tüm uygulama önyüz sitilleri burada ve bu ön yüz sitilleri yazılımcılar tarafından kolaylıkla değiştirilebilirler.

Uygulamayı deneyelim şimdi:

Stlye.xmal ile tüm  uygulama görünümünü değiştirebilirsiniz. Birden çok resource dosyası ile farklı görünüşler elde edebilirsiniz. Ne yazık ki silverlight uygulamamızda dinamik olarak resourceleri değiştiremiyoruz. Uygulama görünümünü tasarım anında App.xmal içinden değiştirmemiz gerekiyor.

<ResourceDictionary.MergedDictionaries>
    <ResourceDictionary   Source="Assets/SeeingSound/Styles.xaml"/>
</ResourceDictionary.MergedDictionaries>

http://expression.microsoft.com/ adresinden Silverlight Navigation Application veya Silverlight Ria Application alanında yer alan şablonları kendi uygulamamızda kullanabiliriz.