1 Şubat 2015 Pazar

Entity Framework Notları : Part 1 (Modelleme Yöntemleri)

Bu yazımda, Microsoft'un bizimle altı sene önce tanıştırdığı Entity Framework (EF) ile ilgili, şu an üzerinde çalıştığım bir proje çerçevesinde aldığım notları size aktarmaya çalışacağım.

Makale boyunca, birçok konuya yönelik yaptığım araştırmaları göz önünde bulundurarak, bir yazılım oluştururken, EF gibi bir ORM(Object Relational Mapping) Framework ile ilgili dikkat edilmesi gereken konulara değineceğim.


Hangi model oluşturma yöntemi tercih edilmeli ?


Öncelikle, bu sorunun kesin bir cevabı olmadığını belirteyim. Demek istediğim, bu sorunun cevabı biraz da kişisel veya takım olarak size kalmış. EF kullanarak ilerleyebileceğiniz, şu an 3 çeşit yöntem var :


  1. Code-First
  2. Model-First
  3. Database-First
Öncelikle, yeni başlayanlar için her birini kısaca özetleyecek olursak ; 

  1. Code-First : Hardcore programming dediğimiz salt programlama ile model oluşturulan yöntem. POCO sınıfları yazarak modelinizi kendi yazdığınız kodlarla oluşturuyorsunuz. Nasıl mı ?
        class Sınıf
        {
            public int ID { get; set; }
            public string Adı { get; set; }
            public virtual ICollection<Öğrenci> Öğrenciler { get; set; } 
        }

        class Öğrenci
        {
            public int ID { get; set; }
            public string Adı { get; set; }
            public virtual Sınıf Sınıfı { get; set; }
        }

     Gördüğünüz gibi, iki sınıfımız var. Birincisi "Sınıf" sınıfımız, diğeri de "Öğrenci" sınıfımız.  Bu ikisinin ilişkisini nasıl tanımladık peki ?   "Navigation Properties (Navigasyon Özellikleri)" sayesinde. Sınıf ile Öğrenci sınıfları arasında bir one-to-many ilişkisi kurduk. Geri kalan tek şey, EF kurulumunu yapmak. Onun da örneği şöyle ki :

        class DenemeContext : DbContext
        {
            public DbSet<Sınıf> Sınıflar { get; set; }   // Bu DbSet ler EF tarafından veritabanına Tablo olarak işlenirler.
            public DbSet<Öğrenci> Öğrenciler { get; set; }

            public DenemeContext()
            {
             
            }

            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                 //  Bu override methodun önemi büyük. Daha sonra değineceğiz.
                base.OnModelCreating(modelBuilder);
            }
        }

    DbContext'ten miras almış olan DenemeContext sınıfı bizim işlemlerimizi gerçekleştirmeye yarayan sınıfımız. Veri işlemlerini yaparken bu sınıfın kopyasını almış bir değişken üzerinden yapıyoruz.

    DenemeContext con = new DenemeContext();
    con.Sınıflar.FirstOrDefault(); // bize Sınıflar tablosundaki ilk veriyi verir.


  2. Model First : Bu yöntem yeni başlayanlar için ve T-Sql bilmeyenler için ideal bir yöntem. Bu yöntemde, Visual Studio'nun size sağladığı bir arayüz sayesinde tüm modelinizi oluşturabiliyorsunuz.
    Model-First örneği
    Tüm entity(varlık/tablo) lerinizi oluşturduktan sonra, gerisini her zamanki gibi EF halledecek ve eğer yoksa veritabınını oluşturacak ve bağlantıları yapacaktır.
  3. Database(DB) First : Açıkçası Code-First ten sonra en çok tercih edeceğim modelleme yöntemidir. Çünkü bir geliştirici olarak, kontrolün elimde olmasını severim ve Code-First'ten sonra gelen ve kontrolü çoğunlukla elinizde tutabileceğiniz yöntemlerden biri de DB-First'tür.
    DB-First modelleme de adından da anlaşılacağı gibi ilk olarak database(veritabanı) modellemesi yapılır. MSSQL kullandığınızı varsayacak olursak DB-First örneğimiz de şu şekilde olacaktır :

    CREATE TABLE Sınıflar (ID int PRIMARY KEY IDENTITY(1,1), Adı nvarchar(255))

    CREATE TABLE Öğrenciler (ID int PRIMARY KEY IDENTITY(1,1), Adı nvarchar(255), Sınıfı_ID int, CONSTRAINT [FK_Sınıflar_Sınıfı_ID] FOREIGN KEY REFERENCES Sınıflar(ID) )

    Bu yöntemi kullanarak bir ObjectContext(veri işlemleri yapmanızı sağlayan nesne) oluşturmak, yaklaşık olarak model-first ile aynı yollardan geçer. Her ikisinde de, projenizde bir EDMX nesnesi oluşacaktır. Ayrıca veritabanındaki model üzerinde yapacağınız her değişiklik ile modelinizi güncellemeniz gerekir.

Konumuz bu olmadığı için, bu yöntemlerin ayrıntılı olarak nasıl kullanılacağını yazmıyorum. Daha çok, performans iyileştirmeleri, model oluşturma teorileri üzerinde yazacağım.

Avantajlar-Dezavantajlar


Bu yöntemlerin her birinin teorik ve pratik olarak birbirlerine göre avantaj ve dezavantajları var.  Bunun için bir tablo oluşturmak isterdim ancak bu tablonun çok doğru olacağına inanmıyorum. Daha çok size benim naçizane tecrübelerime dayanan görüşlerimden bahsedeceğim.

Öncelikle Model-First'ü aradan çıkaralım : 

Daha önce de söylediğim gibi yeni başlayanlar ve t-sql üzerinde çok fazla bilgisi olmayanlar için ideal bir yöntem. Tamamıyla Visual Studio üzerinde built-in olarak gelen designer sayesinde, sadece bir diagram çizmeniz yeterli.Korkmayın, sırf model-first kullanıyorsunuz diye herhangi bir EF özelliğinden geri kalmıyorsunuz ancak tek sorun birçok şey EF'nin kontrolünde oluyor ve sizin bu konu üzerinde pek fazla müdaheleniz olamıyor.

Peki bu neden kötü birşey ?  Şöyle ki, bir geliştirici her zaman sadece yazılımı oluşturmaktan kaçınarak, o yazılımın performansını, tutarlılığını da göz önünde bulundurmalı. Bu gibi konuları göz önüne alırsak, aslında Code-First veya DB-First ile yapabileceğiniz birçok manüel değişiklikten mahrum kalıyorsunuz. (Aslında kalmıyorsunuz ama karmaşık EDMX dosyalarının model oluştururken kullandığı  T4 Template lerinin içerisinde gerçekten rahatlıkla kaybolabilirsiniz )


DB-First


DB-First model örneği
Eğer SQL seviyorsanız sizin için mükemmel. Kontrolün yine çoğu sizin elinizde. Ancak işinizi ikiye bölmek zorunda kalıyorsunuz. Bir taraftan kod yazmak için IDE'ye döneceksiniz, diğer taraftan modeli yazmak/güncellemek için SQL kodlarına. İkisi arasındaki bağlantıyı çok iyi kurmanız gerekir, özellikle de bir takım olarak çalışıyorsanız. Ayrıca, tam olarak sql kodlarını yazdığınız platforma bağlı kalacaksınız. Bunu MySql, MsSql farklılığı olarak düşünmeyin. Örneğin bir ara başıma gelen, MSSQL 2008 R2 - 2005 farklılığı gibi. 2008 R2 "date" türünü desteklerken 2005 desteklemiyor. Evet, küçük bir sorun ama yine de bir sorun... O yüzden bu metodu kullanacaksanız gerçekten buna emin olmanız gerekiyor...

Code-First

Bu üç methodun arasında Code-First benim favorim. Kontrolün tamamı geliştiricinin elinde, EF'nin karışmamasını istediğiniz herşeyi engeleyebilir, farklı bir yorum katmak istediğiniz yerlerde, bunu gerçekleştirebilirsiniz. Platform spesifik olarak çalışmaz, karmaşa söz konusu değildir (tabi bana göre).

Ancak Code-First'ün kendi dezavantajları yok mu ? Tabi ki var... En önemlisi de, "Model Pipeline" nın sebep olduğu performans sıkıntıları ...

Nedir bu "Model Pipeline" ?
Model Pipeline, kodladığınız modelin EF tarafından her programı çalıştırdığınızda belleğe alınan, ilişki şemasının bir görüntüsüdür diyebiliriz. Yani neyin nereye bağlı olduğunu, neyin ne olduğunu bu pipeline belirler. Pipeline data(veri) tutmaz. Sadece modelin ilişkilerinin şemasıdır.

Bu model view(görüntü) larının oluşması, ilk kez programınızı çalıştırıyorsanız (modelinizin de büyüklüğüne bağlı olarak) gerçekten çok uzun sürebilir. (Benim yazdığım bir yazılımda bu 3 dakika kadar sürmüştü) Dikkatinizi çekmek istediğim bir nokta, programınızı ilk kez çalıştırdınız ve kapattığınızda EF bu viewları herhangi bir yere kaydetmez. Yani her programınızı açışınız aslında EF için ilk açışınızdır ve her seferinde bu viewları oluşturmaya çalışacaktır.

Bunun bir çaresi yok mu ? Olmasaydı, kimse Code-First kullanmıyor olurdur herhalde. Çünkü gerçekten can sıkıcı bir durum....

Ne zaman çıktığını bilmiyorum ama, geçenlerde okuduğuma göre (bulamadım makaleyi) VS2015 üzerinde built-in olarak gelecek, Entity Framework Power Tools ile (veya başka 3. parti eklentiler ile) bu durumdan kurtulmak mümkün.

Bu araç sizin için, compile-time sırasında Code-first view oluşturarak, DbContext'inizin ismiyle birlikte kaydedecektir. Örneğin :

DenemeContext.cs
DenemeContext.Views.cs

Böylelikle, programınız her çalıştığında pipeline ı tekrar tekrar oluşturmaya kalkmayacaktır, siz de zamandan kazanacaksınız. Tabi, burada da ufak bir noktadan bahsedeyim, her model değişikliğinizin ardından bu viewları güncellemeniz gerekir.

Hardcore Programming 

Code-First kullanırken, en sevdiğim noktalardan biri de herşeyin "Hardcore Programming" dediğimiz (benim "Salt Programlama" diye tabir ettiğim) yöntemin kullanılması. Yukarıda ki örneğimizden de görebileceğiniz gibi herşey POCO sınıflar ile halledilebiliyor. Peki bunun neresi güzel ?

Programlama dilinin her tarafından yararlanabiliyorsunuz... İster Interface kullanın, isterseniz bu sınıflara methodlar ekleyin. Herşey serbest. Çünkü EF sadece sınıfa ait olan Property leri görecektir.
Methodlar, fieldlar herhangi bir şekilde EF nin aklını karıştırmayacaktır. Tabi, auto-property leri kullandığımızı varsayarsak...

Code-First ün bu konudaki tek eksiği, "Concrete-Class" dediğimiz salt sınıflardan başka birşey görmüyor olması.

Nedir bu Concrete-Class ? 

Concrete-Class (Sade, salt sınıflar) , bildiğimiz normal sınıflardır. Abstract sınıflar veya interface ler gibi birer kopyası alınamayan sınıflar değillerdir. Örneğin  ::

    class Sınıf
    {
        public int ID { get; set; }
        public string Adı { get; set; }
        public virtual ICollection<Öğrenci> Öğrenciler { get; set; }
    }

bir concrete-class örneği olarak verilebilirken,

abstract class SınıfBase
    {
        public int ID { get; set; }
        public string Adı { get; set; }
    }

veya

interface ISınıf
    {
        int ID { get; set; }
        string Adı { get; set; }
    }

birer concrete-class değillerdir ve bunların birer kopyası alınamaz.

Code-First modelleme yöntemi, bu tarz nesneleri veritabanı oluştururken önemsemez. Örneğin,

    class Sınıf
    {
        public int ID { get; set; }
        public string Adı { get; set; }
        public virtual ICollection<Öğrenci> Öğrenciler { get; set; }
        public IÖğretmen Öğretmen { get; set; }
    }


    interface IÖğretmen
    {
        int ID { get; set; }
        int Adı { get; set; }
        Sınıf Sınıfı { get; set; }
    }


"Sınıf" sınıfımızdaki "Öğretmen" property si, EF tarafından ignore(göz ardı) edilecektir. Çünkü bu property tipi bir concrete-class değildir ve EF bunu veritabanına yansıtmaz.

Bunun neresi kötü peki ? OOP açısından bu birçok noktada önünüze engel koyar. Ancak tabi şundan da bahsedeyim, DB-First veya Model-First yöntemlerinde zaten interface veya abstract düşüncesi hiç yok. Code-First üzerinde en azından interface veya abstract sınıfları birer yol gösterici olarak kullanabilirsiniz. Örneğin :



    interface ISınıf
    {
        int ID { get; set; }
        string Adı { get; set; }
        ICollection<Öğrenci> Öğrenciler { get; set; }
    }

    class Sınıf : ISınıf
    {
        public int ID { get; set; }
        public string Adı { get; set; }
        public virtual ICollection<Öğrenci> Öğrenciler { get; set; }
    }


    class Öğrenci
    {
        public int ID { get; set; }
        public string Adı { get; set; }

        public Sınıf Sınıfı { get; set; }
    }

Her ne kadar, Öğrenci sınıfında "Sınıfı" property sini "Sınıf" türünde kullanıp, "ISınıf" türünde kullanamıyor olsakta, en azından bir interface sayesinde OOP mantığı uygulayabiliriz.
(Bu arada şunu da belirteyim, EF'nin şu an için böyle bir özelliği yok, ama NHibernate'in var. )


Peki neden OOP kullanmak isteyesiniz ? Ya da neden bunu EF 'nin sınıfları üzerinde isteyesiniz ?

Şöyle ki, atıyorum WPF ile çalışıyorsunuz ve sürekli binding(veri bağlama) yapıyorsunuz. Eğer daha önce WPF kullandıysanız, INotifyPropertyChanged interface'inin ne kadar önemli olduğunu biliyorsunuzdur. Tabi bunu bir ViewModel üzerinde de kullanabilirsiniz, ancak direk olarak entity sınıfı üzerinde kullanabileceğinizi bilmek te sizi rahatlatabilir.

Ya da ikinci senaryo, ortak noktası bulunan birkaç sınıfın tümünün bir metodu barındırmasını istiyorsunuz. Bunun için neye ihtiyacınız var ? Bir interface veya abstract class a ...  (Yukarıdaki örnek gibi). Gönül rahatlığıyla kullanabilirsiniz.



Part-1 üzerinde anlatacaklarım bu kadar. Part-2 ye geçtiğimizde biraz da size MVVM biraz da Association(ilişkilendirme) mantıkları hakkında karşılaştığım durumları aktarmaya çalışacağım.

Eğer yanlış bildiğim bir nokta , eklemek istediğiniz bir şeyler veya bir sorunuz varsa lütfen çekinmeden yorumunuzu yapın...

7 Mayıs 2014 Çarşamba

Dikkat : Sahte(Spam) "Ödeme Makbuzu","Fatura","Ödeme Bilgisi" Mailleri

Son günlerde , yaklaşık 10 kere gelen bir mail dikkatimi çekti ve üzerinde biraz inceleme yaptım.

Mail genelde Hintçe isimler altında gönderiliyor ve alıcıları da tamamen gizlenmiş durumda oluyor. Ayrıca her gelen mailde bir ".jar" dosyası veya ".rar" dosyası eki bulunuyor. İlgimi çekmesinin birincil sebeplerinden biri de ".jar" tipinde gelen mail ekiydi zaten. Ayrıca maili incelediğimde böyle bir firma/kişi veya kuruluştan alışveriş yapmadığımı anlamam ile birlikte, gelen mailin spam olduğuna kanaat getirmiştim.

İnternet üzerinden,daha ilk geldiği zaman bu maili araştırdım ancak bunun bir virüs olduğuna dair bir örnek bulamamıştım. Daha sonra bugün tekrar araştırmam sonucu gördüm ki, CISCO (buradan okuyabilirsiniz), Symantec (buradan okuyabilirsiniz) gibi firmaların bu konuda makaleleri var.

Mail ile gönderilen ek ya JRAT denilen Java programlama dili ile yazılmış bir Trojan virüsü veya Self-Extracting Archive(Kendi-Kendini Çıkaran Arşiv) modunda gönderilen bir executable(exe/program) dosyası. Her ikisinde de amaç bilgisayarınıza Trojan virüsü yerleştirip kişisel bilgilerinizi ele geçirmek hatta daha da kötüsü bilgisayarınızın kontrolünü ele almak.

Virüsün yakalanma oranı bir firma tarafından 7/50(kaynak) belirlenmiş. Bu zaten düşük bir oran olmakla birlikte birçok anti-virüs veya spam yakalama programı bu dosyayı yakalayamamaktadır.

Toparlamak gerekirse bu virüse karşı alınabilecek en büyük önlem yine kendi kararınız olacaktır. Eğer gözünüze eki olan şüpheli bir mail geliyorsa okumadan silin. 

Bu arada gelen tüm mailler birbirlerinden farklı isimlerden gelmekte, farklı bilgiler yer almakta ve farklı dosya ekleriyle gönderilmektedir. Ancak örnek olması açısından bana gelen maili sizlere şu şekilde gösterebilirim. 

Gönderen : hitendra68@gmail.com
Konu : Payment Slip of $16.00
Alıcılar : Gizli
Mesaj : 

--

M/s.PAPPUSHETH & COMPANY

B-101, ''KIRTI PLATINIUM APARTMENT'', 1ST FLOOR,
OPP. SILVERSTAR COMPLEX & SBI BANK, GOTA ROAD,
BETWEEN GOTA CHANDLODIA BRIDGE,
CHANDLODIA-AHMEDABAD-382481.(GUJARAT-INDIA).
CONTACT PERSON:- HITENDRA . M. TRIVEDI

VIBER AND WHATS APP 9033 805 805 / 9624 223 223 /94291 19218
SKY PE NAME :- HITENDRA.TRIVEDI66EMAIL ID:- HITENDRA68@GMAIL.COM
PAPPUSHETHANDCOMPANY@GMAIL.COM


Umarım yardımcı olabilmişimdir.

6 Ocak 2014 Pazartesi

AngularJS , Nedir , Nasıl , Nerede , Hangi Durumlarda Kullanılmalıdır ? Yararları ve Zararları Nelerdir ?

AngularJS.. Ne yalan söyleyeyim adamlar Javascript üzerinde MVC(Model-View-Controller) mimariyi tabiri câizse "resmen öttürmüşler".

Tabi kendi resmi internet sitesine (ki buraya tıklayarak gidebilirsiniz) bakacak olursanız, onların tabiriyle bu çatı bir MVC değil MVW mimari...

Açıklamalara göre "W" burada "Model-View-Whatever Works For You" yi temsil ediyor yani "Model-View-Hangisi İşinize Gelirse".Tabi burada kastedilen şey bu framework'u bir MVC mimarisi olduğu kadar isterseniz bir MVVM(Model-View-ViewModel) ya da MVP(Model-View-Presenter) mimarisi olarak da kullanabilirsiniz. Orası size kalmış.

Ve kendim kullandığımdan söylemiyorum, doğru kullanıldığında gerçekten çok hızlı ve stabil kod yazmanızı sağlayabilecek, eğlenceli bir framework.
Ancak tabi dikkatli kullanıldığında ! (ne demek istediğimi az sonra açıklayacağım )

Tabi kullanıp-kullanmayacağımızı,işimize yarayıp-yaramayacağını öğrenmek için öncelikle ne olduğunu öğrenmek lazım.

Angular.JS Nedir ?

Daha deminde anlattığım gibi AngularJS, MVW mimarisine sahip bir Javascript framework'tür.

  • Genellikle SPA(Single-Page Applications/Tek-Sayfa Uygulamalar) tabanlı uygulamalar için kullanılır(ancak tabi diğer uygulamalar için de kullanılmasında bir sakınca yoktur).
  • Browser-Based(tarayıcı-ağırlıklı) uygulamalar için uygundur.
  • Dinamiktir(data binding vs. anlamında)
Nasıl kullanılır ?

Kullanımı oldukça basittir.Öncelikle kütüphaneyi buradan veya angularjs.org adresinden çekin. Daha sonra HTML dosyanıza 
<script type="text/javascript" src="angular.min.js"></script> şeklinde ekleyin. Daha sonra da kodunuzu yazmaya başlayın :) (geleceğiz oralara da)

AngularJS her ne kadar javascript ile yazılmış olsa da biraz kendine özel bir framework'tür diyebiliriz. Dosyayı refere ettikten sonra ilk önce bir ng-app yani AngularJS applikasyonu yazmanız gerekmektedir. Gözünüz korkmasın ama gayet basit ; 

** Bu örneklere resmi internet sitelerinden de ulaşabilirsiniz ancak ben de arada belirtmiş olayım

ilk önce bir javascript dosyası oluşturup içerisine applikasyonumuzu yazalım.

örneğin ; mainapp.js

şablon şu şekilde ilerler ;
ilk önce AngularJS içerisinde bulunan angular namespace'inin altında built-in gelen "module" methodunu kullanarak modülünüzü yazarız ki bizim senaryomuzda appIsmi.

var appIsmi = angular.module('appIsmi',[]);


// daha sonra bu modüle bir controller oluştururuz ;

appIsmi.controller('Kontrolum',function($scope){
//bu kısımda da verimizi elle yazacağız örnek 
$scope.liste = [ {'isim' : 'Microsoft' } , { 'isim' : 'Google'} ];
});


Şimdi burada hemen değinmem gereken bir iki nokta var. 

  1. $scope nedir ? $scope nesnesi, model,control,view arasında iletişim sağlayan objedir. Tüm model-view-controller nesneleri birbirlerinden ayrı olmalarına rağmen onları bir senkronizasyon içerisinde tutar. Yani mesela model üzerinde yaptığınız değişiklik anında bir view üzerine aktarılıyorsa (ki denediğinizde göreceksiniz, zaten AngularJS böyle çalışıyor) bunu sağlayan $scope nesnesidir. 
  2. var appIsmi = angular.module('appIsmi',[]); kısmındaki [] kısmı. Buraya normalde AngularJS üzerine ekstradan eklemek istediğimiz bir modülün ismini gireriz. Örneğin ;  var appIsmi = angular.module('appIsmi',['ngSanitize']); // sanitizasyon(bir çeşit kod temizleme, angular bunu html üzerinde kullanır)
  3. appIsmi.controller('Kontrolum' kısmı ; controller nesneleri birer variable olarak değil bu şekilde string olarak belirtilirler. ( Aslında daha farklı yöntemleri de bulunmaktadır )
Mainapp.js dosyamızı hazırladır. Sonra ?

Şimdi sıra HTML'de. Sihrin oluştuğu yer. 

Öncelikle HTML üzerinde applikasyonumuzu tabiri caizse tanıtmamız gerekmektedir. Bunu da bizim basit örneğimizden devam ettirecek olursak ;


<html ng-app="appIsmi">

şeklinde yapıyoruz.
Geriye de sadece "view" kısmı kalıyor. Oraya da şöyle basitçe değinmek istiyorum. Örneğin elimizdeki verilerin listesini yapalım.Ve bunlara ekleme yapan bir input yapalım.

<div ng-controller="Kontrolum">

    ng-repeat döngüsüyle elimizdeki verileri yazdıralım(bu metod ve nesneleri daha sonraki makalelerimde eğer zamanın olursa açıklamaya çalışacağım)

   <ul ng-repeat="nes in liste">
      <li>{{nes.isim}}</nes>
   </ul>

   <input type="text" ng-model="eklenecek">
   <button ng-click="ekle()">Ekle</button>

</div>

Burada önemli bazı noktalar bulunmaktadır.
  1. "ng-" attribute'leri. AngularJS içerisinde gelirler ve view üzerinde kontrol sağlamamızı sağlarlar. ng yazdıktan sonra yazacağınız kısım işlevinize göre değişir. Örneğin biz burada ng-app , ng-controller, ng-model ve ng-click kullandık. Zaten tireden sonra gelen kısımdan da az çok anlarsınız neyin ne olduğunu.
  2. {{nes.isim}} kısmı ; şimdi doğal olarak merak ediyorsunuzdur. Bu iki süslü parantez de neyin nesi ? Bu parantezler angular ekibi tarafından konulmuştur.  İki süslü ortasına yazılan nesne her zaman bir expression(ifade) olmalıdır. Şöyle bir örnekte verebiliriz {{ nes.isim == "Microsoft" ? "Evet" : "Hayır" }} . Tek bir süslü kullanımında genelde dynamic expression'lar devreye girer. Örneğin bizim modelimizde $scope.liste dizisinin içerisinde şöyle bir durum söz konusu olsaydı ; { "isim" : "Microsoft" , "silindi" : true } biz bunu html içerisinde css class'ları belirlemek için kullanabilirdik. Mesela <li ng-class="{silik : silindi}"> buradaki "silik" css class'ımızın ismi iken "silindi" bize dinamik olarak değer döndürecek değişken. Bu expression sayesinde angular "microsoft" içerikli nesneyi yazdırırken "class='silik'" diye yazdıracaktır çünkü "silindi" nin değeri true 'dur.
  3. ng-click="ekle()" kısmı. Buradaki ekle() metodunu eğer kalkıpta javascript içerisine normal bir metod olarak yazarsanız çalışmayacaktır.Buradaki metoduda mecburen controller altında belirtmeniz gerekir. Ha, aklınız karışmasın, eğer "onclick" yazmış olsaydık normalde nasıl kullanıyorsak öyle kullanmaya devam edebilirdik. Ancak, eğer ng-click kullanıyorsak az sonra göreceğimiz örnekteki gibi metod belirlemiz gerekmektedir.
Şimdi mainapp.js üzerinde birkaç değişiklik yapmamız gerekiyor ;
    appIsmi.controller('Kontrolum',function($scope){
        $scope.liste = [{"isim":"Microsoft","aktif":true},{"isim":"Google","aktif":true},{"isim":"Apple","aktif":false}];
        $scope.eklenecek = "";
            $scope.ekle = function(){
                $scope.liste.push({"isim":$scope.eklenecek,"aktif":false});
            }
        });

Son olarak test ettiğinizde göreceksiniz ki, kodumuz çalışmaktadır. Şimdi teknik kısmı atladıktan sonra gelelim diğer önemli konulara....
Nerede ve hangi durumlarda kullanılır/kullanılmalıdır ?
Aslında bu soruya en iyi cevabı siz vereceksiniz tabi, ben sadece kararı almanızda yardımcı olmaya çalışacağım.

Projenizin türü nedir ?
Eğer projeniz bir back-end projesi veya hiçbir arama motorunda çıkmaya ihtiyaç duymayan bir projeyse devam edin. Muhtemelen çok akıllıca bir seçim olacaktır. Ancak eğer front-end bir proje üzerinde çalışıyorsanız(ya da front-end i siz yazıyorsanız) ve eğer SEF ve SEO sizin için çok önemliyse açıkçası çok da tavsiye etmem.
Çünkü dikkat ederseniz direkt olarak HTML kaynak  kodlarının arasına data-binding yapıyoruz. Her ne kadar biz bunu dinamik bir kaynağa bağlamış olsak dahi, arama motorunun botu bu verileri okuyamayacaktır... mı ? Tam olarak hayır.
Burada tabi hemen Google'ın Ajax Crawling sistemine değinmek lazım. Eğer daha önce Ajax Crawling yapmışsak biliyoruzdur ki, SEO ve SEF açısından bu mevzu tam bir baş belası olabilir. Ancak Google'ın getirdiği bazı düzenlemeleri ile HTML Snapshot taktiği kullanılarak indeksleme'de verinin düzgün bir biçimde anlaşılması sağlanabilir.
Ama bu demek değildir ki avantajlısınız. Bir kere, Html Snapshot için ya ekstra kod yazacaksınız ya da 3. parti kütüphaneler ( PhantomJS vs. ) kullanarak bunu sağlayacaksınız. Bu bana göre büyük bir dert. Ancak eğer bunu göze alabilirseniz tabi ki AngularJS yine iyi bir çözüm.
Ancak eğer bir back-end projesi yapıyorsanız, hele bir de SPA olarak tasarladıysanız...AngularJS tam sizin için.
Neden diyeceksiniz, burada da artık "Yararlar ve Zararları" kısmını açıklamanın zamanı geldi...

Yararlar
  1. Direktifler yazabilirsiniz ; şöyle ki :

        <slayt adi="falan"></slayt>
        ya da
        <div bizim-slayt></div>
    
Custom(İsteğe Özel) HTML tagları veya attribute'lar aracılığı ile "User Control" nesneleri... Bunun bize ne kadar büyük kolaylıklar getirebileceğini hepimiz tahmin edebiliriz.

  • ng-repeat 'in sağladığı kolaylıkla kod kalabalığından kurturuluz. Bir nesneyi birden fazla kez tekrar edeceksek bunu ufak bir template yazarak halledebiliriz.
  • Çok karmaşık değildir. Biraz üzerinde durduğunuzda çok kısa sürede çözersiniz.
  • RESTFul aksiyonlar standart haline getirilmiş ve AngularJS'e entegre edilmiştir.
  • MVVM sayesinde, model üzerindeki değişiklik anında view üzerine yansır.
  • Unit-Testing için idealdir.
  • $routeProvider nesnesi sayesinde (özellikle SPA için) harika bir routing sistemi kurabilirsiniz. AngularJS kendi içerisinde bunu bir-iki modülle yapabilmektedir.
  • Takım projelerinde, iş paylaşımı yapılabilmesini sağlar.
  • En önemlisi ... Google tarafından geliştirildiği için stabilite bakımından çokta bir endişeniz olamaz :)


  • Zararlar
    1. (Üstü çizili çünkü tam olarak bir sorun sayılmaz)Direktiflerin IE8 uyumluğu bir sorun olabilir.Ancak AngularJS üzerinde yayınlanan bir makalede bu aşılmıştır.
    2. Bahsettiğimiz SEO ve SEF biraz sıkıntılı olabilir.

    Gördüğünüz gibi tam olarak bir zarardan/sıkıntıdan da bahsedemiyoruz. En azından ben daha çok büyük bir sıkıntıyla karşılaşmadım. Umarım biraz olsun yardımcı olabilmişimdir. Edindiğim bilgileri, vaktim oldukça paylaşmaya devam edeceğim.
    Sağlıcakla.

    4 Ocak 2014 Cumartesi

    SSD almalıyım ? Alırsam nasıl birşey olmalı ? SSD neden daha iyi ? Ucuzu hangisidir ?


    Geçenlerde bilgisayarımda oluşan bir sıkıntı nedeniyle HDD(Hard Disk Drive) değiştirme kararı aldım.  Tabi bu devirde alınacak en mantıklı depolama seçeneklerinden biri de SSD(Solid State Drive) almak ve ben de buna karar verdim.

    Uzun bir araştırmadan sonra gördüm ki, mantıklı ve ucuz bir seçim yapmak kolay değil. SSD ler ile ilgili birçok makale ve doğal olarak birçok fikir var.
    Ancak merak edip bakmışsanız görmüşsünüzdür ki SSD ler alışık olduğumuz HDD piyasası gibi ucuz donanımlar değiller. Bu yüzden insan doğru bir karar vermek istiyor.

    Bu konuda benim kararım Samsung 840 EVO Serisi oldu.

    Şimdi gelelim karar aşamasına ...

    1. Soru , SSD Nedir ?

    ** Bu kısımda biraz teorik teknik detaya kaçabiliriz, isterseniz son paragrafa atlayın.

    SSD (Solid State Drive) ler birer veri depolama üniteleridir. Ancak HDD iler arasında çok büyük farklılıklar bulunmaktadır.

    Çoğumuzun kullandığı HDD'lerin çalışma mantığında, diskler(tabaklar) üzerine manyetik olarak yazılmış veriyi , bir motor aracılığı ile çok hızlı bir şekilde döndürerek veriyi okumak veya üzerine veri yazmak vardır. HDD'ler de veri silmek diye birşey yoktur. 

    Tabi , "Nasıl veri silemiyoruz, ben siliyorum işte .. "  diye bir soru uyanabilir aklınızda. Şöyle ki, siz işletim sisteminizde (Windows , MacOS , Linux vs. ) bir dosya sildiğinizde o dosya aslında tam olarak silinmez, sadece işletim sistemi o dosyayı sizden gizler. Bir HDD üzerinde veri, yerine yeni veri gelene kadar bekler.(Tabi olağan durumlardan bahsediyoruz. Bazı durumlarda bunu aşmak mümkündür.) Yerine yeni veri gelen sektör, yeni veriyi eski verinin direkt olarak üzerine yazar. Böylece veri HDD'den silinmiş varsayılır.

    Ancak bu durum SSD ler üzerinde böyle değildir. SSD'lerin çalışma mantığı RAM(Random Access Memory/ Rastgele Erişilebilir Hafıza) mantığı gibidir.Veriler direkt olarak entegre devreler üzerine yazılırlar. 

    Aslında, yazma ve okuma işlemleri geleneksel HDD işlemleri gibidir ancak SSD ler içerisinde hiçbir mekanik parça yoktur. HDD ler gibi tabakların dönmesini falan beklemek zorunda kalmadığınız için yaklaşık 3-4 kat daha hızlı veri okur,yazarsınız (alacağınız SSD ye göre değişir tabi).

    Ve Modern SSD lerin çoğunda TRIM özelliği bulunmaktadır ki bu özellik HDD'lerde yoktur. Nedir bu diyecek olursanız, TRIM komutu OS(Operating System/İşletim Sistemi) tarafından SSD'ye gönderildiği zaman, istenilen bloktaki tüm verileri sıfırlar. Böylece daha iyi bir performans, stabilite sağlamış olursunuz.

    Özetleyecek olursak, donanımsal olarak SSD'ler, HDD'lere göre daha gelişmiş bir sisteme sahiptirler. RAM mantığında çalışmaları, mekanik parçalarının olmamaları performans arttırımında fayda sağlarken, bir taraftan da sesten kurtulmuş ve enerji tasarrufu yapmış olursunuz.

    2. Soru , bir SSD'ye ihtiyacınız var mı ?

    Bu sorunun cevabı gerçekten size kalmış aslında ama ben de aklınızda birkaç fikir oluşmasını sağlamak için bazı şeyler ekleyeceğim.

    Aradığınız şey performans ise, örneğin ;

    1. Oyun oynarken, oyunun açılış hızının, dosya yükleme hızının yükselmesini istiyorsanız,
    2. İş dünyasında, sürekli depolama aygıtından veri çeken bir program kullanıyorsanız
      1. Mesela grafik ve video programları ( 3ds Max, Indesign, Illustrator, Premiere, After Effects) (Tabi bu tip programlar daha çok RAM kapasitesi ve CPU hızıyla alakalıdır ancak inanın bana SSD de farkettirir)
      2. Programlama programları (Visual Studio, Eclipse, IntelliJ Idea vs.)
    3. Ya da bilgisayarım beni kanser edecek, tüm donanımlarını değiştirmem lazım diyorsanız
    SSD tam size göre.... mi ? Tabi burada birde fiyat devreye giriyor .

    3. Soru , fizibilite sonucu ne olacak ?

    Tamam, SSD performans arttırımı sağlıyor ancak, bu gerçekten size gereken birşey mi buna iyi karar vermelisiniz. Çünkü görmüşsünüzdür ki SSD'ler bugün en ucuz 100-200$ + KDV gibi fiyatlardan başlıyor ve ucunun nereye kadar gittiğini tahmin bile edemezsiniz.

    Böyle bir donanımı aldıktan sonra, yaptığınız yatırıma değecek mi ?

    Bence ;
    Eğer iş dünyası ile ilgili bir yatırımsa, kesinlikle bunu yapmalısınız. Ancak sadece oyun oynamak amaçlıysa ve siz kendinizi her zaman oyun oynayan biri olarak (hardcore gamer diyoruz biz buna) görmüyorsanız çok gereksiz bir yatırım olabilir. Veya bu donanımı alacağınız bilgisayar sadece bir veri yedekleme bilgisayarı da olabilir ki o zaman kesinlikle tavsiye etmiyorum.En azından bu fiyatlara...


    Gelelim benim verdiğim karara ;

    Yazının başında da söylediğim gibi ben Samsung 840 EVO serisinden bir SSD aldım. Bu kararı verirken çok araştırdım ve gördüm ki Samsung SSD piyasasında gerçekten yer edinmiş bir firma.

    Performans ile ilgili testlere baktığımda, Samsung 840 EVO serisinin gerçekten güzel puanlar aldığını gördüm.

    Ancak daha ucuz yollu birşey olsun diyorsanız, tavsiye edebileceğim markalar arasında Sandisk ve OCZ var .

    Bir de bu arada incelemek isterseniz ; 

    SSD Benchmark Sonuçları linkinden sıralamayı kendiniz de görebilirsiniz. Tabi bu cihazların çoğu Türkiye'ye ihraç edilmiyor ancak olanların arasından uygun fiyata göre seçim yapabilirsiniz. 

    Umarım yardımcı olabilmişimdir.


    3 Ocak 2014 Cuma

    Yerel Bilgisayarınızda IIS Websitesini Yayınlayın

    Bu yazımızı biraz kısa ve teorik tutacağız,

    Diyelim ki elinizde bir web uygulaması veya bir web sitesi var. Ve siz bu internet sitesini internet üzerinden paylaşmak istiyorsunuz.

    Bunu ağınızda bulunan diğer bilgisayarlarla yapmak gayet kolay. Yapmanız gereken tek şey, Windows Güvenlik Duvarı (Firewall) üzerinde, web applikasyonunu yayınladığınız port için bir istisna(exception) oluşturmak.
    Böylece ağınızdaki bilgisayarlar sizin bilgisayarınız üzerinde bulunan IIS üzerine ;

    http://IPADRESI(LAN/Yerel):PORT   --> (Örnek) http://192.168.2.3:99

    şeklinde ulaşabilirler. 

    Peki ama bunu intranet(yerel ağ) içerisinde değil de internet üzerinde paylaşmak istiyorsanız ne olacak ?

    Hemen çok ufak bir senaryo... Kendi ofisinizde ki bilgisayarda IIS üzerinde FalancaLTD diye bir web sitesi(veya applikasyon,normalde farketmez ancak biz buradaki senaryoda bir websitesi olarak alacağız) var ve 99 portu üzerinden yayın yapıyor. Ve tabi bu arada sizin LAN(yerel) IP'niz de 192.168.2.3

    Şimdi intranet üzerinde nasıl ki yerel ip adresini yazıp, iki nokta üst üsteyi de koyup portu da yazdıktan sonra giriş yapabiliyorsak, internette de bunu yapabiliriz... mi ? Teorik olarak evet ancak burada önümüze birkaç engel çıkacak tabi(güvenlik engeli).

    Dışarıdan bir bilgisayar sizin WAN(genel ip diyelim) IP adresinizi (Hadi 99.88.77.66 olsun) kullanarak giriş yapmaya çalıştığında öncelikle varsa modeminizdeki firewall engel koyarak bağlantıyı koparacaktır. Eğer bu engel aşılırsa bu seferde Wİndows Firewall aynı işlemi uygulayacaktır.

    Bunları aşmanın yollarına gelelim ;


    1. Windows Firewall üzerinde bir "Gelen Kuralı" belirleyerek TCP Protokülün sizin kullandığınız portuna (bizim senaryomuzda 99) izin verin.
    2. Modeminiz üzerindeki firewall'a ( bu konuda kesin olamıyorum çünkü tahmin edersiniz herkesin modemi birbirinden farklı ) aynı istisnayı ekleyin. * Not : eğer böyle bir seçeneğiniz yoksa büyük ihtimalle firewall'ı devre dışı bırakmak zorunda kalırsınız.
    Böylece IIS, gelen isteği güvenlik duvarlarına takılmadan almış olacak ve web sitesini serve(sunacak) edecektir... mi ? Büyük ihtimalle hayır ! 

    Peki neden ?

    Birçok modem dışarıdan gelen isteklerde, istemcinin bir porta direkt olarak ulaşmasına izin vermezler. Burada devreye neredeyse her modem üzerinde bulunan NAT (Network Address Translation / Ağ Adresi Dönüştürme ) devreye girer.

    NAT[kaynak], modem üzerine gelen bir isteği IP maskeleme yaparak başka bir IP (LAN IP) üzerine gönderebilir. 

    Buradaki mantık nedir ? 

    İstemcinin http://99.88.77.66:99 (A İsteği olarak yazacağım bundan sonra) adresli isteği sizin modeminiz üzerine gelecektir. Modeminiz bu işlemi LAN IP'ye dönüştürerek bir response(cevap) almaya çalışacaktır. Peki dönüştüreceği LAN IP yi nereden bilecek ? O ağda sizden başka 20 bilgisayar olabilir ancak sadece sizin IIS'iniz FalancaLTD adlı internet sitesini yayınlıyor.

    Varsayılan olarak modeminiz "Varsayılan Ağ Geçidi" üzerine yönlendirme yapacaktır. 

    * Hani şu Windows'ta Denetim Masası > Ağ ve Paylaşım Merkezi penceresinde "Bağlantılar" yazısının tam karşısında bulunan mavi linke(genellikle Ethernet yazar) tıkladığınızda ve "Ayrıntılar" butonuna bastığınızda listenin alt sıralarında çıkan "Varsayılan Ağ Geçidi" ... :)

    Varsayalım ki bizim ağ geçidimiz 192.168.2.1 olsun... Modem otomatik olarak sizin A isteğinizi http://192.168.2.1:99 olarak algılayacaktır ve tabi bu adreste bir IIS olmadığı için hiçbir karşılık alamayacaksınız.

    İşte burada adres yönlendirme yaparak bu işin içinden çıkacağız.
    1. Modeminizin arayüzünü açın ( Genellikle tarayıcınıza "Varsayılan Ağ Geçidi" IP adresini yazarak erişebilirsiniz, örneğin, http://192.168.2.1)
    2. Arayüzden NAT ayarlarını bulun ( artık nerede olduğunu bulmak size kalmış ) ( Mesela TP-Link modemlerde "Gelişmiş" menüsü altında)
    3. Eğer varsa "NAT etkin" seçeneğini işaretleyip NAT yi aktif hale getirin.
    4. Ayağa kalkıp bir 30m koşup geri gelin :) ( spor her zaman iyidir )
    5. NAT üzerine yeni bir kural ekleyin ve düzenleme kısmında şunlara dikkat edin;
      1. Yerel IP Adresi sorulacaktır burada IIS kurulu olan bilgisayarın LAN(Yerel) IP'sini girmeniz gerekmektedir. (192.168.2.3 / senaryoya göre )
      2. Başlangıç ve bitiş portları olacaktır ( yada birden fazla port ekleme seçeneği ) , başlangıç portuna A isteği üzerine gelen port (Örnek : 99.88.77.66:99) , bitiş portuna ise IIS üzerinde yayın yapan sitenin portunu girin ( bilmiyorsanız %99.99 ihtimalle 80 'dir ya da IIS'de internet sitenize tıklayıp sağdaki "Eylemler" panelinde "Siteye Gözat" yazan yerden görebilirsiniz)
      3. Bir kural ismi isteyebilir, istediğiniz herhangi birşeyi girin.
      4. Eğer protokol soruyorsa, bir protokol seçin ( %99.99 TCP )
      5. Ve kaydedin.
    Eğer DMZ seçeneği açıksa(tabi varsa) ve IP adresi olarak da IIS'in bulunduğu LAN IP adresi(192.168.2.3) girilmişse, zaten internet sitesini görebiliyor olursunuz. Daha kısa bir işlemdir ancak tavsiye etmem çünkü DMZ gelen tüm istekleri kabul etmenize sebep olur ve bu da güvenlik açığı demektir.


    Bu işlemleri yaptıktan sonra tekrar deneyin, eğer hala bağlanamıyorsanız ve NAT işlemlerini doğru yaptığınızı varsayıyorsanız büyük ihtimalle istek başka bir Firewall'a takılmıştır.

    Tabi başta bahsetmeyi unuttum , bilgisayarınızda yüklü 3. parti her antivirüs yazılımı, firewall vb. yazılımlar için de aynı istisnaları girmeniz gerekmektedir.


    Artık başka bir bilgisayardan WAN IP adresiniz ve IIS sitesinin portu yazıldığında artık otomatik olarak internet sitesini görebileceksiniz.

    Göremezseniz bana sorabilirsiniz. :) 

    "Bu yazıyı kısa tutacağız" deyince inandınız değil mi ?