23 Eylül 2011 Cuma

Bir ülke iflas ederse ne olur?


Bir ülkenin iflas etmesi o ülkenin yükümlülüklerini yerine getirememesi anlamına geliyor. Yani bir ülke memur maaşlarını, borçlarını ödeyemiyorsa teknik anlamda iflas etmiş olarak kabul ediliyor.

Bugüne kadar hiçbir ülke memurlarına maaş ödemeyle, alacaklılarına borç ödeme arasında seçim yapmak zorunda kaldığında alacaklıları tercih etmedi. Yani aralarında silahlı kuvvetlerinde yer aldığı memurlara maaşları öyle ya da böyle ödenirken, diğer alacaklılara para yok deniliyor.
Bir ülke ben borçlarımı ödemiyorum dediğinde, banka ya da kişilerde olduğu gibi alacaklılar kapısına gelip, mallarına haciz koyamıyor.
Peki iflas eden ülkenin başına neler geliyor? Bugüne kadar ülke iflaslarının hiçbirisinde devletler alacaklılarına size hiç para ödemeyeceğim demedi.
Genelde yapılan 'Ben iflas ettim, size olan borçlarımın bir kısmını sileceğim. Kalanını da uzun bir vadede ödeyeceğim' şeklinde bir dayatma oluyor.
Örneğin Arjantin 2003 yılında 'Ben iflas ettim' dediğinde borçlarının dörtte üçünü sildi. Arjantin'e borç veren dev bankalar ve bu ülkenin bonolarını alan 500 bin yatırımcı paralarının yüzde 75'ini kaybetti.
Ancak bir ülkenin 'Ben borçlarımı ödemiyorum' demesi öyle kolay değil. Böyle bir şey yapan ülkeye yatırımcılar bunun faturasını daha sonra mutlaka ödetiyor.
O ülkenin bir daha dünya piyasalarından kolay kolay borç bulması mümkün olmuyor. Bulunan borcun faizi de son derece yüksek oluyor.

16 Ağustos 2011 Salı

Excel'de hücre içinde bir alt satıra nasıl geçilir?

Excel'de bir hücreye bir satırdan fazla veri girmek istiyorsanız Enter tuşuna bastığınızda o hücre içinde bir alt satıra geçmek yerine bir sonraki hücreye geçtiğini acı bir şekilde farkedeceksiniz :mrgreen: 

Çeşitli tuş kombinasyonları deneyip doğru olanı buluncaya kadar sinir katsayınızı artırmadan önce cevabı forumlarda arama başlayan arkadaşlar için

Excel'de bir hücrede bir alt satıra geçmenin formülü: ALT + ENTER

27 Temmuz 2011 Çarşamba

C# Generic Sınıflara Giriş #2

Generics Nedir

Generics size tip-güvenliği ve performansı düşünmeden generic sınıflar yapabilmenizi sağlar.Sunucuyu yanlızca bir kere generic sunucu olarak implement edersiniz, aynı zamanda istediğiniz tip için kullanabilrsiniz. Bunu yapabilmek için < ve > parantezlerinin içine kullanacağımız tipi yazarız. Mesela aşağıda bir generic stack yapısının nasıl olduğu  görülmektedir:


public class Stack
{
   T[] m_Items; 
   public void Push(T item)
   {...}
   public T Pop()
   {...}
}
Stack stack = new Stack();
stack.Push(1);
stack.Push(2);
int number = stack.Pop();
Kod Blok 2 generic stack yapısını göstermektedir.  Kod Blok 1 ile Kod Blok 2 yi karşılaştırın göreceksiniz ki, Stack tanımı haricindeki her yerde  Code block 1 deki object yerine Kod Blok 2, ye T yerleştirilmiştir:
public class Stack
{...}
Generic stack yapısını kullanırken compiler ı generic parametre olan T yerine hangi tipin kullanılacağını hem stack yapısını tanımlarken hemde başlatırken bilgilendirmemiz gerekiyor:

Stack stack = new Stack();
Compiler ve runtime geri kalan herşeyi yapar.
Kod Blok 2. Generic Stack Yapısı
public class Stack
{
   readonly int m_Size; 
   int m_StackPointer = 0;
   T[] m_Items;
   public Stack():this(100)
   {}
   public Stack(int size)
   {
      m_Size = size;
      m_Items = new T[m_Size];
   }
   public void Push(T item)
   {
      if(m_StackPointer >= m_Size) 
         throw new StackOverflowException();
      m_Items[m_StackPointer] = item;
      m_StackPointer++;
   }
   public T Pop()
   {
      m_StackPointer--;
      if(m_StackPointer >= 0)
      {
         return m_Items[m_StackPointer];
      }
      else
      {
         m_StackPointer = 0;
         throw new InvalidOperationException("Cannot pop an empty stack");
      }
   }
}

23 Temmuz 2011 Cumartesi

Site Haritası Oluşturma ve Web Yönetici Araçlarına Kayıt

Google, Web Master Tools ile hızlı, kolay ve iyi şekilde siteniz hakkında detaylı bilgiye sahip olabilir. Aynı zamanda Web Master Tools'a kayıt olmak Arama Motoru Optimizasyonu (SEO) içinde faydalı olacaktır. Web Yönetici Araçları'na blogunuzun site haritasını yükleyebilir ve böylelikle Google'ın sizin siteniz hakkında bilgi sahibi olmasını sağlayabilirsiniz.


Web Yönetici Araçlarını Kullanmak için Sebepleriniz Var

1. Site haritası oluşturmak.
2. İçerik Analizi Yapabilmek; Sitenize giden bağlantılar, Anahtar Kelimeler, İç bağlantılar, Abone istatistiklerinizi inceleyebilirsiniz.
3. Sitenizdeki URL'leri Bulunamadı, Erişilemiyor, HTTP, Site Haritaları içerisinde, Zaman aşımına uğradı, robots.txt ile kısıtlanıyor, İzlenemiyor gibi kategorilere ayrılmış listeler yardımı ile kolayce görüntüleyebilme ve varsa sorunları düzenlem imkanı.
4. Harici Bağlantılar: Sitenize başka sitelerce verilmiş olan bağlantıları görüntüleme imkanı.
5. Harici Bağlantıların içeriği hakkında bilgi.
6. URL İndekslenme: Google tarafından hale hazırda indekslenmiş olan bir içeriğin indekslenmesini istemiyorsanız URL'yi kaldırma imkanı.

Liste benzer maddelerle daha da uzatılabilir.

Wordpress gibi diğer blog platformlarında hazır eklentilerle oluşturulabilen Site Haritasını Blogger'da oluşturmak için atom.xml beslemesini kullanabiliriz. Eğer halen site haritanızı Web Yönetici Araçlarına kaydettirmediyseniz, vakit kaybetmeden Web Yönetici Araçlarına kayıt olun. Kayıt işleminden sonra var olan sitenizi kayıt ettirmelisiniz. Size verilecek olan kodu istenlen yere yerleştirin ve sitenizi doğrulayın.

Doğrulama işleminden sonra, site haritası eklemek istediğiniz blogunuzu Web Yönetici Araçlarıda seçin. Açılan pencerede sayfanın solunda yer alan Kontrol Panelinden Site Yapılandırma > Site Haritaları yolunu izleyin ve Bir Site Haritası Gönderdin seçeneğine tıklayın açıan kutucuğa alttaki gibi Site Haritanızı ekleyin;

http://blogadiniyaz.blogspot.com/atom.xml?redirect=false&max-results=100
ya da
http://www.siteadiniyaz.com/atom.xml?redirect=false&max-results=100

* Eğer besleme için Feedburner kullanıyorsanız, ?redirect=false kodunu eklediğinizde hata kodu alabilirsiniz.
* max-results=100 kodu sitenizde yer alan son 100 yazınızın site haritanızda yer almasını sağlayacaktır.

Eğer sitenizde 100'den fazla sayıda yazınız varsa;
atom.xml?redirect=false&start-index=101&max-results=100

Eğer sitenizde 200'den fazla sayıda yazınız varsa;
atom.xml?redirect=false&start-index=201&max-results=100

Daha fazla yazınız varsa benzer şekilde ilerleyebilirsiniz.


Site Haritası Hazırlamak için Farklı Yöntemler


En önerilen yöntem Web Yönetici Araçları ile Site haritası oluşturmaktır. Ancak merak edenler için site haritası oluşturmaya olanak sağlayan birkaç siteden de bahsetmek isterim.

* xml-sitemaps.com sitesiyle bilgisayarınıza herhangi bir program yüklemeden, bedava olarak site haritası oluşturabiliyorsunuz. Oluşturulan site haritası Google, Yahoo!, Live Search başta olmak üzere tüm arama motorlarına uygun. 500 sayfalık limiti var.

* WriteMaps, online olarak site haritası oluşturmanıza, düzenlemenize ve paylaşmanıza izin veren web tabanlı ücretsiz bir araç.

* FTP tipindeki Blogger blogları için; Gsite Crawler

gibi Site Haritaları oluşturabileceğiniz farklı sitelerde kullanılabilir.

13 Temmuz 2011 Çarşamba

İpucu: SQL Server Servislerini Komut Satırından Yönetme

SQL Server Servislerini tıpkı diğer servsilerde olduğu gibi komut satırından başlatabilir, durdurabilir veya duraksatabilirsiniz. Varsayılan veritabanını yönetmek için şu komutları komut satırında kullanabilirsiniz:

NET START MSSQLSERVER SQL Server'ı bir servis olarak başlatır.
NET STOP MSSQLSERVER Servis olarak çalışan SQL Server'ı  durdurur.
NET PAUSE MSSQLSERVER Servis olarak çalışan SQL Server'ı duraksatır.
NET CONTINUE MSSQLSERVER Duraksatılan SQL Server'ı kaldığı yerden devam ettirir.

Diğer adlandırılmış SQL Server örneklerini ( Named Instances) yönetmek için şu komutları kullanabilirsiniz:


NET START MSSQLSERVER$instancename SQL Server'ı bir servis olarak başlatır.
NET STOP MSSQLSERVER$instancename Servis olarak çalışan SQL Server'ı  durdurur.
NET PAUSE MSSQLSERVER$instancename Servis olarak çalışan SQL Server'ı duraksatır.
NET CONTINUE MSSQLSERVER$instancename Duraksatılan SQL Server'ı kaldığı yerden devam ettirir.

28 Haziran 2011 Salı

SSMS 2008 - Saving changes is not permitted

Saving changes is not permitted. The changes you have made require the following tables to be dropped and re-created.” hatası SQL Server 2008 den sonra ortaya çıkan ve bizleri bir miktar bunaltan bir hata çeşididir. Çünkü hatanın çözümü için sizlere önerdiği yol değiştirmek istediğiniz tablonun yeniden oluşturulmasıdır.













SQL Server 2008 ile beraber ortaya çıkan bu hata çeşidi, sizlere SQL Server Management Studio nun bir hediyesidir. SQL Server Management Studio sizlerin yanlışlıkla bir tabloda kritik bir değişilik yapmamanız için bu sistemi oluşturmuştur. Ancak bu engel özellikle tasarım aşamasında tabloların çok sık değiştiği zamanlarda, aşırı can sıkıcı olabilmektedir. Dolayısı ile bu engelden kurtulmak özellikle veritabanı tasarlarken sizi çok rahatlatacaktır.
Çözüm yolu ise gene SQL Server Management Studio(SSMS) dan geçer. Başlangıç olarak Tools menüsü altından Options seçeneğini seçiniz. (SSMS – Tools – Options)

Açılan pencere de sol menüden Designer bölümünü seçtikten sonra , sağ tarafa açılan panel de bulunan Prevent saving changes that require table re-creationalanındaki kutudaki seçimi kaldırısanız SSMS az önceki hatayı bir daha göstermeyecektir.

21 Haziran 2011 Salı

Veritabanı indeksleme nasıl çalışır?


Neden ihtiyaç duyulur?
Veriler disk tabanlı belleklere depolandığında, bloklar halinde depolanır. Bu bloklara bütünlük içinde erişilmesi, onları atomik disk erişim operasyonları yapar. Disk blokları genelde bağlı listeler gibi yapılandırılmıştır; her ikisi de verinin tutulduğu kısım ve bir sonraki düğüme gösteren pointer kısmından oluşur ve her ikiside ardarda depolanmak zorunda değildir.
Sıralama yapılmamış bir alanda arama yapmak Lineer Arama yapmayı gerektirir, bu da N/2 blok erişimi gerektirir. Buradaki N tablonun disk üzerinde bulunduğu blok sayısıdır. Eğer bu alan key yani anahtar olmayan bir alan ise arama N tane blok erişimi gerektirir.
Halbuki sıralanmış bir alan olsaydı Binary Arama kullanılabilir, bu da log2 N blok erişimi gerektirir. Bununla birlikte key olmayan alan sıralanmış ise tablonun geri kalanı duplicate değerleri bulmak için aranmaz. Çünkü alan sıralanmış olduğu için aranandan değişik bir değere erişildiğinde arama bitmiş demektir. Böylece performans önemli ölçüde artar.
İndeksleme nedir?
İndeksleme belirli sayıdaki kaydın birden fazla alanda sıralanması demektir. Bir tablodaki bir alanda indeks oluşturunca, alanın değerini ve bu değerin ilişkili olduğu kaydı işaret eden bir pointer tutan diğer bir veri yapısı oluşturur. Daha sonra bu indeks yapısı üzerinde Binary Arama yapılabilmesi için sıralanır.
İndekslemenin dezavantajı disk üzerinde ekstradan alana ihtiyaç duymasıdır.
Nasıl Çalışır?
Öncelikle örnek bir veritabanı tablo şemasının ana hatlarını çizelim;
Alan adı           Veri tipi      Disk üzerinde kapladığı alan
id (Primary key)   Unsigned INT   4 byte
firstName          Char(50)       50 byte
lastName           Char(50)       50 byte
emailAddress       Char(100)      100 byte
Not: varchar yerine char kullanılmasının sebebi değerin disk üzerinde kapladığı alanın kesin boyutu belirlemek için kullanılmıştır. Bu örnek veritabanı 5 milyon row a sahiptir ve indexlenmemiştir. Değişik sorguların performansı analiz edilecektir.Bunlar id(sıralanmış anahtar alanı) ve firstName(sıralanmamış anahtar olmayan alan) dir.
Örnek 1
Örnek olarak verilen veritabanı r = 5,000,000 kayıtlı, R = 204 byte sabit boyutta kayıt uzunluğu ve blok boyutu B = 1024 byte tır. Tablonun bloklama faktörü bfr = (B/R) = 1024/204 = 5 her bir disk bloğundaki kayıt sayısı. Tabloyu tutmak için gerekli toplam blok sayısı N = (r/bfr) = 5000000/5 = 1,000,000 blok.
id alanındaki arama ortalama N/2 = 500,000 blok erişimi gerektirir, id alanının aranan değerde olup olmadığını kontrol etmek için. Ama id alanı sıralı olduğu için Binary Arama yapılarak ortalama log2 1000000 = 19.93 = 20 blok erişimi ile bulunabilir. Gördüğünüz gibi bu müthiş bir gelişmedir.
Şimdi firstName alanı ne sıralanmıştır, ki böyle olduğu için Binary Arama yapamayız, ne de değerler unique dir, bu yüzden de tablo sonuna kadar aranmalıdır yani N = 1,000,000 blok erişimi gerektirir. İşte burada indekleme yapmak çok faydalıdır.


Söylendiği gibi index kaydı sadece indexlenen alanı ve orijinal kayda işaret eden pointer ı barındırmaktadır. firstName alanı için index şeması aşağıdaki gibidir:
Alan adı            Veri tipi      Disk üzerinde kapladığı alan
firstName           Char(50)       50 byte
(record pointer)    Special        4 byte

Örnek 2
Örnek olarak verilen veritabanı r = 5,000,000 kayıtlı ve index kaydı uzunluğu R = 54 byte ve varsayılan blok büyüklüğü B = 1,024 byte tır. İndeksin bloklama faktörü bfr = 1024/54 = 18 herbir disk bloğu için kayıt sayısı. Tabloyu tutmak için gerekli blok sayısı N = (r/bfr) = 5000000/18 = 277,778 bloktur.
Şimdi firstName kullanarak yapılan arama indeks yapısından faydalanarak performansı arttırır. Yani bu indeksin Binary Aramasının ortalama blok erişimi log2 277778 = 18.08 = 19 dir.
Ne zaman kullanılmalı?
Görüldüğü gibi indeks oluşturmak fazladan disk alanı gerektirir. İndeksleme yapısı sadece aramalarda işe yarar. Yeni kayıt güncelleme ve silme işlemlerinde ekstra işlem zamanı ve disk alanı gerektirir. Bu yüzden sadece aramaları hızlandırmak için yapılmalı ve yüksek veri bulunan tablolarda gerekli alanlar için yapılmalıdır.

17 Haziran 2011 Cuma

C# Static Constructor

C# ta static constructor için performans değerlendirmesi: Microsoft ve birçok kod geliştirici static constructorların ciddi bir yük getirdiği konusunda uyarıyorlar. Static constructorlara aynı zamanda type initializer de denir, çünkü bunlar tiplere referans verirler, instancelara değil. Aşağıda C# dilinde static constructorlar için yapılan test bulunmaktadır. Hangisinin yararlı olduğuna karar verebilirsiniz.


Örnek

Aşağıda static contructoru bulunan ve bulunmayan olarak iki sınıf bulunmaktadır. Kullandığınız çoğu sınıfın static constructoru yoktur. Sonuca göre static constructorlar tipe her ulaştığınızda ciddi bir yavaşlamaya sebep oluyor.

Static Constructor a sahip bir class [C#]

/// /// Bu tip static constructora sahiptir.
/// 
static class HasStaticConstructor
{
    ///     /// Public field
    ///     public static int _test;

    ///     /// Static constructor public alanı initialize eder
    ///     static HasStaticConstructor()
    {
 _test = 1;
    }
}

Static Constructoru olmayan bir class [C#]

/// /// Bu tip static constructora sahip değildir.
/// 
static class NoStaticConstructor
{
    ///     /// Public field initialize edilir
    /// 
    public static int _test = 1;
}

Benchmark (Karşılaştırmalı Test) notları

Döngü: 1000000000
Detaylar:    _text alanı her döngüde erişilir.

Static constructor performans testi

Sınıf 1: Static constructoru olan
Zaman:    3208 ms

Sınıf 2: Static constructoru olmayan
Zaman:     319 ms

Özet

Static constructor kullanmak uygun olabilir, ama çok yavaşlar.Runtime bunları inline atamaları optimize edebildiği yolla optimize edecek kadar akıllı değil. Bazen lazy loading kullanmak uygun olabilir. ( Lazy Loading: bir değişkenin her erişildiğinde null kontrolü yapılıp eğer null ise initialize etmek).

13 Haziran 2011 Pazartesi

ASP.NET MVC nedir, ne işe yarar, niçin ve ne zaman tercih edilmelidir?

ASP.NET MVC’yi anlamak için “WebForms”un ne olduğunu bilmek ve anlamış olmak gerekir. Bundan dolayı öncelikle biraz webformsa değinmek istiyorum.
Klasik ASP ile web geliştirenlerin .NET’e geçişi ile birlikte hayatlarına giren ilk şey “WebForms” olmuştur. Asp.Net programlamada başlangıç seviyesinde, mantığı tam olarak anlaşılamasa da, giriş seviyesi bir programcı dahi webformsu aktif olarak kullanır. Basit bir şekilde anlatmak gerekirse; bir aspx sayfasında bulunan asp.net server kontrollerine (textbox, dropdown, vb.) girilen verilerin programatik olarak işlenmesi için koda gönderilmesini sağlayan sayfa yapısına webforms diyebiliriz. Bu işlemi gerçekleştirmek için bize yardımcı olan mekanizmalar vardır. Postback ve Viewstate bunların başında gelir. Postback bu kontrollerdeki veriyi koda gönderme eylemine verilen isimdir. Viewstate ise postback öncesinde bu formlara girilmiş olan verilerin postback sonrasında tekrar kullanılabilir olmasını sağlayan mekanizmadır. Örneğin aşağıdaki gibi basit bir aspx sayfamız olsun.

Bu sayfadaki textbox’a bir yazı girip, checkbox’a tick atıp, butona tıklandığında textboxa girilen yazıyı sayfanın başına yazdırdığımızı düşünelim. Bunun için Visual Studio’da designerdaki butona çift tıklarız ve bizi code behind’a yönlendirir ve bu buton için bir event oluşturur. Bu eventin içine Response.Write(TextBox1.Text) benzeri bir kod yazarız. Daha sonra bu sayfayı çalıştırıp, butona tıkladığımızda sayfa bir kere refresh yapar (kendini tazeler) ve tekrar aynı sayfayı açar.

Textboxa girdiğimiz yazı, olması gerektiği gibi sayfanın başında gözükür. Ayrıca textbox’ın içinde yazı hala duruyordur ve checkbox da ticklenmiş durumdadır. Oysa sayfa kendini refresh etmiştir. Refresh eyleminin aynı sayfayı tekrar açtığını düşünürsek (adres çubuğundaki url değişmez), o sayfaya ilk defa girildiğinde olduğu gibi boş bir şekilde açılması beklenir. Bunu test etmek için sayfa boş iken textboxa bir yazı girin checkbox’a tick atın ve daha sonra browser’ınızın refresh butonuna basın. Bunu yaptığınızda göreceğiniz üzere textbox’taki yazı kaybolur ve checkbox boşalır. Sayfa ilk açıldığı şekline geri döner. Fakat butona tıklayıp sayfayı refresh ettirdiğinizde her şey yerinde duruyordur. İşte buradaki butona tıklama eylemi sonucu sayfanın refresh yapmasına postback denir. Bu refresh sonunda textbox’a girdiğimiz yazının durması ve checkbox’ın tickli kalmasını da viewstate mekanizması sağlar. Postback ile textbox’taki yazı koda gönderilir. Kod bu yazıyı alır, işler, sayfanın başına yazar ve tüm bunlar refresh anında olur. Refresh tamamlandığında her şey istediğimiz gibidir. İşte tüm bu olaylar zincirinin ve mekanizmaların tamamına “WebForms” denir.
Basit anlamda webformsun işleyiş şekli ve yapısı böyledir. Fakat Asp.Net MVC’de yapı bu şekilde değildir. MVC’de postback, viewstate, codebehind, server kontrolleri (textbox, checkbox) ve bu kontollerin eventleri yoktur. “Olamaz! Bunlar olmadan sayfa nasıl çalışır!” dediğinizi duyar gibiyim. Evet alışık olduğumuz bu yapı Asp.Net MVC’de farklı bir şekildedir. Peki neden farklı? Bu yapı gayet güzel çalışıyor. Bunu neden farklı bir yapıda kullanma ihtiyacı duyuyum ki? Benzeri soruların cevabı ise; webformsun bu yapısının bazı dezavantajları olduğu ve bu dezavantajların mvc’de olmamasıdır. Bazı web projelerinde webformsun birazdan bahsedeceğim dezavantajları tahammül edilemeyecek derecelere ulaştığı için Asp.Net MVC, WebForms’a alternatif olarak geliştirilmiştir. Fakat bu MVC’nin daha iyi, webformsun daha kötü olduğu veya mvc’nin webformsun yerine geçeceği gibi bir anlam taşımamaktadır. Projenin türüne göre tercih edilebilecek birer alternatiftirler.
Şimdi gelelim webformsun dezavantajlarına. Öncelikle bu dezavantajlardan bahsedeceğim. Daha sonra mvc’nin bunları nasıl çözdüğünü elimden geldiğince anlatmaya çalışacağım. Bu çözümleri incelerken mvc’yi de anlamaya çalışmış olacağız.
1.) Viewstate, sayfadaki server kontrollerinin durumunu hafızasında tutmak için client tarafında gizlenmiş bir hidden input oluşturur. Bu input webforms ile geliştirilmiş her aspx sayfasında vardır. Web browser’ınızda herhangi bir aspx sayfasının kaynağına baktığınızda “__VIEWSTATE” isimli bu inputu görebilirsiniz.

<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKLT
c1MDU0Nzg2MWQYAQUeX19Db250cm9sc1JlcXVpcmVQb3N0QmFja0tleV9fFgEFCUNoZWNrQm94
MX5gT8EYawMsUp79Tkt2Gz2HkU/i" />


Gerçek hayat uygulamalarında bu inputun value’su o kadar büyür ki boyutu yüzlerce kilobyte’ı bulur. Bu da client tarafında gereksiz bir yavaşlığa neden olur. Server tarafında ise bu viewstate değerini oluşturmak ekstra iş yükü demektir. Hele bir de günde milyonlarca kez ziyaret edilen bir web projesi ise, bu yavaşlık ve iş yükü tahammül edilemez olur. Yukarıda bahsettiğim gibi Asp.Net MVC’de viewstate yoktur. Bundan dolayı mvc’de böyle bir yavaşlık söz konusu değildir. Peki mvc’de viewstate yoksa sayfadaki kontollerinin durumunu nasıl hafızada tutacağız? Merak etmeyin Asp.Net MVC’de bu işi gören bir mekanizma var ve bu mekanizma ne client’a ne de server’a ekstra iş yükü getiriyor. Bu işi http’nin yapısına uygun bir şekilde çok daha doğal yollar ile gerçekleştiriyor.
2.) Webforms’da sayfa yaşam döngüsü (page life cycle) vardır. Yukarıdaki örnekte kısaca bahsettiğim üzere sayfanın çalışma anında bir tür olaylar zinciri gerçekleşir. Butona tıklandığında o butonun click eventi tetiklenir, daha sonra postback başlar, veriler koda gider, kod veriyi işler ve tekrar sayfaya gönderir. Basit bir uygulamada kısa ve hızlı bir döngüdür bu. Fakat kompleks uygulamalarda maalesef bu kadar hızlı olmamaktadır. Hele bir de o sayfada onlarca server kontrolü bir aradaysa çok daha uzun sürer. Eventler havada uçuşur. Önce hangisi tetiklendi? Sonra hangisi tetiklenecek? Şimdi ne olacak? Aynı anda birden fazla eventi nasıl tetiklerim? Bir sürü karmaşa ortaya çıkar. Codebehind event metotlarıyla dolar. Hangi event hangi kontrolündü karıştırırsınız. Designera geri dönüp o kontrole çift tıklayıp codebehind’taki onun eventine gitmek gibi bir zahmete katlanırsınız. İnanın bana büyük web uygulamalarında bu sizi çığırından çıkarır. Asp.Net MVC’de bu eventlerle boğuşmak zorunda değilsinizdir. MVC sizi Page_Load eventindeki “Page.IsPostBack değilse” kontrolünü yapma derdinden de kurtarır.
3.) Webforms’da asp.net server kontolleri otomatik olarak html elementlerine dönüştürülür. Siz o kontrolün html’ine müdahale edemezsiniz. Yaptığımızın işin web sitesi geliştirmek olduğunu düşünürsek web’in temeli olan html’de tam kontrol sahibi olamamamız hoş bir durum değildir. Özellikle standartlara uyumlu sayfa tasarlama gibi bir kaygımız varsa (ki olmalıdır) server kontolleri size bu esnekliği sağlamamaktadır. Server kontrollerinin css’lerinde de tam kontrol sahibi değilizdir. Ayrıca server kontolleri bazen gereksiz html kodları da üretebilmektedir. MVC’de server kontrolleri olmadığı için standart html elementlerini kullanırız. Bu da size sayfanızın html’inde tam kontrol verir.
4.) Büyük web projelerinde N-Layer, N-Tier, vb. metodolojileri kullanarak programınızın mantık (logic) kısmı ile tasarım (presentation) kısmını birbirinden ayırırsınız. Böylece projenin yazılımsal olarak yönetimi daha kolay olur. Webformsdaki codebehind yapısı aslında bu metodolojilere ters düşmektedir. Çünkü presentation layer’ınızda yoğun olarak kod yazarsınız. Bir çok mantıksal işlemi aspx sayfasına bağlı codebehind’da gerçekleştirirsiniz. MVC’de tasarım ile mantık çok iyi bir şekilde ayrılmıştır. Tasarımı bir kere bitirdiğinizde tekrar tekrar oraya geri dönmek zorunda kalmazsınız. Artık işiniz daha çok mantıksal işlemlerdir, bu katmana yoğunlaşırsınız.
Temel olarak bu dört dezavantajın yanında diğer bazı dezavantajlar da mevcuttur. Fakat konuyu uzatmamak için onlara bu yazıda değinmeyeceğim. Yukarıdaki dezavantajlar ele alındığında büyük bir web projesi için Asp.Net MVC’nin tercih edilmesi akıllı bir yol olarak gözüküyor değil mi? Peki mvc sadece bu dezavantajları gideren bir yapı mı? Kesinlikle hayır. Asp.Net MVC’nin bize kazandırdığı daha birçok yeni ve kullanışlı özellik de mevcut. Bunlardan en önemlisinin “Routing” mekanizması olduğunu söyleyebilirim. Routing, bir aspx sayfasına URL üzerinden gelen çağrıları anlamlı hale getirdikten sonra işlenmesi için mantıksal yapının olduğun koda (logic) yönlendirme işini gerçekleştiren mekanizmadır. Örneğin “www.abc.com/kategori/altkategori/sayfa” şeklinde bir url olduğunu düşünelim. Bu url’i web browserda adres çubuğuna girip enter’a basıldığı an asp.net mvc’de ilk olarak routing mekanizması çalışır. Routing bu url’deki ana domainden (www.abc.com) sonra gelen “/” ile ayrılmış kısımları (kategori, altkategori, sayfa) parçalar, daha sonra mantıksal kodun (logic) içerisinde bunlara uygun olan metotları bulup oraya yönlendirir. Logic’de gerekli işlemler yapıldıktan (veritabanından verilerin çekilmesi, işlenmesi, vb.) sonra tekrar Routing devreye girer ve işlenmiş bu verilerin gösterileceği uygun aspx sayfasını bulup oraya yönlendirir. Routing'in sağladığı bu yapı sayesinde url’ler çok daha anlamlı hale gelir. Böyle olunca da arama motorları bu url’leri daha iyi indeksler ve siteniz üst sıralarda çıkar. Webforms’da bu yapıyı oluşturabilmek için ekstra zahmete girersiniz. Webforms’da url rewrite denilen teknik ile bu işlem gerçekleştirebilmektedir fakat mvc’de olduğu kadar hızlı ve doğal değildir.
Routing’i anlatırken aslında Asp.Net MVC’yi anlamaya bir giriş yapmış olduk. Genel itibariyle mvc’nin çalışma mantığı routing’deki bu yapı üzerine kuruludur. URL’den bir istek gelir, o isteğe uygun metot (Controller) bulunur, bu metod aldığı bu isteği yerine getirmek için uygun business logic metotlarını (Model) çalıştırır ve son olarak buradan dönen anlamlı veriler uygun aspx sayfalarına (View) yönlendirilir.
Burada parantez içerisinde belirttiğim “Model”, “View”, “Controller”lar da bir araya gelip MVC’yi oluşturur.

Bu yazıda Asp.Net MVC’ye detaylı sayılabilecek bir giriş yapmış olduk. Planım bunu bir yazı dizisine çevirip MVC’nin tamamını detaylı bir şekilde incelemek ve sizlerle birlikte örnek bir uygulama geliştirmek. Umarım bu planımı gerçekleştirebilirim. Bir sonraki yazıda Model-View-Controller yapısının nasıl çalıştığına göz atıp, örnek bir asp.net mvc projesi oluşturarak bunu pekiştiririz. Şimdilik bu kadar. Diğer yazıda görüşmek üzere.

25 Mayıs 2011 Çarşamba

Metadata Nedir?

Son zamanlarda IT sektöründe sıkça duymaya alıştığımız ifadelerden biri oldu "metadata". Peki nedir bu metadata?
Birebir anlam olarak baktığımızda metadata, bilgi hakkında bilgi olarak tanımlanıyor. Ancak tabi bu haliyle soyut ve yetersiz bir tanımlama olarak kalıyor. Biraz somutlaştıralım:

Metadata, bilgi kaynaklarım beni yanıltmıyor ise ilk olarak kütüphanecilik alanında icat edilen bir kavram. Bir kütüphanede pek çok kitap, yani aslında yüklü miktarda bilgi bulunmaktadır. Ancak sorun, bu bilginin nasıl indexleneceği, yani hangi bilgiye hangi kitaplardan ulaşılabileceği, hangi kitabın içeriğinin aşağı yukarı ne olduğu... İşte burada metadata yani bilgi hakkında bilgi yardıma koşuyor. Metadata, ille de içeriğin türü hakkında (örneğin anahtar kelimeler veya bilimsel bir makalenin "abstract" kısmı) olmak zorunda değil. Basım evi, yayın tarihi, baskı sayısı da birer metadatadır.

Metadatanın IT alanındaki kullanımlarına çok basit örnekler vermek gerekirse, veritabanı sitemlerinde her tablonun ve alanın yanındaki onun hakkındaki açıklama alanları, web sitelerinin "header" bölümünde bulunan "meta tagleri" içindeki web sitesini tanımlayıcı bilgiler gösterilebilir.

IT ve otomasyon sistemleri yaygınlaştıkça, ortada çok büyük data, datadan üretilen enformasyon ve hatta işlenmiş bilgi havuzları oluştu. Şu an IT dünyasının gündemi, oluşan bu bilgiye en kısa yoldan nasıl ulaşılıp, bilginin nasıl yönetileceği olmaya başladı. Bu yüzden metadata kavramını gittikçe daha da çok duyacağız.

24 Mayıs 2011 Salı

Generic Kullanımı #2

Generic Kısıtlamaları

C# ta generic-tip parametrelerinin yerine hangi kısıtlamalarda client-tanımlı parametrelerin kullanılacağını derleyiciye belirtmek zorundasınızy. Üç tip kısıtlama vardır. Türeme kısıtlaması derleyiciye generic-tip parametrenin hangi temel tipte class veya interface den türemesi gerektiğini belirtir. Varsayılan yapıcı (default constructor) kısıtlaması derleyiciye generic-tip parametresinin default public contructor a (parametresiz public constructor) sahip olduğunu gösterir. Referans/Değer tip kısıtlayıcısı generic tip parametrenin referans mı yoksa değer tipindemi olduğunu sınırlar. Bir generic tip birden fazla kısıtlayıcı barındırabilir.
Şunu da belirtmek lazım ki bu kısıtlayıcılar opsiyoneldir, ama generic-tip parametreler kullanırken bunları kullanmak mecburi gibidir. Bunları kullanmadığınız sürece object-tip parametrelerde olduğu gibi daha fazla tip-güvenlik kontrolleri yapmanız gerekir.Kısıtlamalar generic-tip metadatanın önemli bir parçasıdır, bu sayede client-side derleyiciside bunun avantajlarından faydalanabilir. Client-side derleyicisi client geliştiricisine kısıtlamalara uymasını zorlayarak tip-güvenliği sağlar.
Kısıtlamaların kullanım ihtiyacına yönelik bir örnek verecek olursak: Bağlı listeye indexleme kabiliyeti ve bir key e göre arama kazandırmak isteyelim

public class LinkedList
{
   T Find(K key)
   {...}
   public T this[K key]
   {
      get{return Find(key);}
   }
}
Bu clienta aşağıdaki kodu yazmasına olanak sağlar.
LinkedList list = new LinkedList();

list.AddHead(123,"AAA");
list.AddHead(456,"BBB");
string item = list[456];
Debug.Assert(item == "BBB");

Arama yapabilmek için tüm listeyi taramak, her bir node un key ini aranan key ile karşılaştırmak ve eşleşen node u geri döndürmek gerekir. Problem şu ki aşağıdaki method derlenmez:

T Find(K key)
{
   Node current = m_Head;
   while(current.NextNode != null)
   {
      if(current.Key == key) //Derlenmez...
         break;
      else
         
         current = current.NextNode;
   }
   return current.Item; 
}
Neden derlenmediğinin sebebi:
if(current.Key == key)
Yukardaki satır derlenmez çünkü derleyici K nin == operatörünü destekleyip desteklemediğini bilemez. Mesela structlar bu çeşit bir gerçekleştirmeyi desteklemez. Bu == operatör kısıtlamasını aşmak için  IComparable arayüzünü kullanabilirsiniz:

public interface IComparable 
{
   int CompareTo(object obj);
}
CompareTo() methodu eşitlik durumunda 0 döndürür, böylece Find() methodu bunu aşağıdaki gibi kullanabilir:

if(current.Key.CompareTo(key) == 0)
Malesef bu kodda derlenmez çünkü derleyici K nın IComparable dan türeyip türemediğini bilme imkanı yoktur.
Siz bunu  IComparable a cast edip kullanabilirsiniz ama bu da tip-güvenliği için pahalıya mal olur:

if(((IComparable)(current.Key)).CompareTo(key) == 0)

Türeme Kısıtlaması

C# 2.0 da kısıtlama tanımlamak için where keyword ünü kullanırız.  where keyword ünü derleyiciye parametrenin neden türemesi gerektiğini belirtmek için kullanırız.

public class LinkedList where K : IComparable
{
   T Find(K key)
   {
      Node current = m_Head;
      while(current.NextNode != null)
      {
         if(current.Key.CompareTo(key) == 0)
            
            break;
         else      
            
            current = current.NextNode;
      }
      return current.Item; 
   }
   //Rest of the implementation 
}
Derleyici burada list in key argümanı için IComparable dan türeme şartı koşucak ve kodu eğer key bundan türemiyorsa derlemiyecektir.
Kısıtlama size IComparable ı kullanmanıza izin verse bile, key olarak değer tipinde, mesela integer tipinde bir değişken kullandığınızda tekrar boxing yapmanız gerekecek. Bu sorunu aşmak için  IComparable kullanmanız gerekecek:

public interface IComparable 
{
   int CompareTo(T other);
   bool Equals(T other);
}
Key için kullanımı aşağıdaki gibidir.

public class LinkedList where K : IComparable
{...}
Kısıtlamalar gerçek türemelerden sonra yazılmalıdır. Mesela LinkedList IEnumerableinterface inden türüyorsa where bundan hemen sonra yer almalıdır:

public class LinkedList : IEnumerable where K : IComparable
{...}
Aynı generic tip parametresinde birden fazla interface kısıtlaması getirebilirsiniz Mesela:

public class LinkedList where K : IComparable,IConvertible
{...}

Her bir generic tip parametre için kısıtlama yazılabilir, mesela:
public class LinkedList where K : IComparable
                             where T : ICloneable 
{...}

Generic tip parametreler için class dan türeme kısıtlamasıda getirebilirsiniz. Ama sadece bir tane belirleyebilirsiniz:
public class MyBaseClass
{...}
public class LinkedList where K : MyBaseClass
{...}

C# kısıtlama olarak başka bir generic tip parametre kullanmanızada olanak sağlar:
public class MyClass where T : U 
{...}

Constructor Kısıtlaması

Generic sınıfın içinde bir generic nesne oluşturmak istediğinizi düşünün. C# derleyicisi clientın kullanacağı tip argümanın tipinde argümanlara sahip bir constructor olup olmadığını bilemez, böylece derleme yapamaz.
Bu problemi aşmak için C# size public default contructor tanımlamanıza olanak tanır. Bu new()kısıtlaması kullanarak yapılır. Örneğin:

class Node where T : new() 
{
   public K Key;
   public T Item;
   public Node NextNode;
   public Node()
   {
      Key      = default(K);
      Item     = new T();
      NextNode = null;
   }
}
Türeme kısıtlaması ile birlikte kullanımı aşağıdaki gibidir:

public class LinkedList where K : IComparable,new() 
{...}

Referans/Değer Tip Kısıtlaması

Generic tip parametresinin değer tipindemi yoksa başka tiptemi olacağını aşağıdaki gibi kısıtlayabilirsiniz:

public class MyClass where T : struct 
{...}
Aynı şekilde referans tipinde olduğunuda class keywordü ile kısıtlayabilirsiniz:

public class MyClass where T : class 
{...}