15 Eylül 2014 Pazartesi

Bir Yazılımcı Şirketten Neden Ayrılır Vol 2 ?

Çok fazla iş değiştirme sirkülasyonun görüldüğü sektörlerden bir tanesi belki de yazılım sektörüdür.
Bu değişimlerin pek çok nedeni olabilir.Bu nedenlerden bazılarını, daha önce Ceyda Anıl hanımın bir insan kaynakları uzmanı gözünden yazmış olduğu yazıyı okuyabilirsiniz.


Ceyda hanımının sıraladığı nedenleri,bende yazılımcı perspektifinden gözlemlediğim tecrübelerle desteklemek istedim.

Peki yazılımcı şirketten neden ayrılır ?
  • Çalıştırdığınız yazılımcıya ağzı laf yapmıyor,ama işi iyi yapıyor gibi bir cümle kurup öküzlükte master yaptığınızı belirtirseniz.
  • Arkadaşlar çok çalışın,şu işleri bitirin tatile götürücem sizi deyip,çalışanın önüne hedef koyup, çalışanın hakkını tatilde yedikten sonra,maaş günü geldiğinde ”zaten bu sıralar işler kesat” gibi üçkağatçılıkta iyi bir seviyeye gelmiş iseniz.
  • Henüz askerlik görevinizi yapmamış ve bu görevin karşılığı olan bedeli,çalışanlarınızın maaşlarını ödemeyip,bedelli ücreti için kullandıktan sonra,hala insanım diye gezebiliyorsanız.
  • İşi teslim edip,müşteriden ödemeyi aldıktan sonra,yazılımcının hakkını ödemek yerine,alkol ihtiyacınızı karşılamaktan geri kalmıyorsanız.
  • Müşteri ile yazılımcı arasına köprü kurup,müşterinin isteklerini dolaylı yoldan kendiniz, doğru bir şekilde anlamadan,dinlemeden yazılımcıya yanlış bir şekilde aktarıp,daha sonra doğru bir iş çıkarmasını beklerseniz ve yanlışın sorumlusu olarak yazılımcıyı görürseniz.
  • Kendi belirlediğiniz mesai saatlerine en başta patron/yönetici olarak uymayıp,yapılması gereken işi mesai saatleri dışına taşırıp,gerekli mesai ücretini ödemek işinize gelmiyor ve çalışanın hakkına girmediğinizi düşünecek kadar pişkin bir yapıya sahipseniz.
  • Mesai saatleri anlaşmanızda hafta içi 08:30 ile 18:00,hafta sonu 10:00 , 15:00 olarak anlaşıp,
    aslında mesai saatlerinizin hafta içi 08:30 ile 17:30,hafta sonu 10:30 , 16:00 olduğunu bilmeyip, dünyadan bihaber yaşıyorsanız.
  • Bir proje sorumluluğunu alıp,yapmayıp,cinsel açlığınızı doyurmak için kimseye haber vermeden yurt dışına çıkıp,saldım çayıra mevlam gayıra şeklinde bir sorumsuzluk abidesi iseniz.
  • Resmi tatilde yazılımcıyı işe çağırıp,resmi tatil gününde bugün niye kod yazmadın,x işi neden y sürede yaptın diyecek kadar pişkinseniz.
  • Proje lideri olarak “Takım çalışmasına yatkın” kavramını kendi işinize geldiği gibi “siz çalışın ben yatayım” gibi yanlış olarak algılayıp uygulamışsanız.Sosyal paylaşım hesabınızda "I did nothing today and still got paid" ibaresini içeren mesajlar paylaşacak kadar pişkinseniz.
  • “Yazılım Geliştirici/Uzmanı” pozisyonu için aldığınız personeli aynı zaman da,”Teknik destek” olarak kullanıyorsanız.Telefonlara bakmaktan kod yazamadığını dile getiren yazılımcıya pişkin bir biçimde “Multithread çalış !” şeklinde bir çözüm önerip,yazılımcının muzdarip olduğu bu konuyu dile getirmesini “Sürekli şikayet ve eleştiri” olarak görüyorsanız.
  • Yazılım ekibi sorumlusu olarak,yazılımcının inisiyatif alıp mesai saatleri dışında çalışıp ürettiği bir üründe,tek satır commitiniz olmadığı halde,takım halinde yaptık diyebiliyorsanız.
  • Yazılım ekibi sorumlusu olarak,bir projenin en önemli değişikliklerinin yapılacağı sırada sorumsuz bir şekilde kimseye haber vermeden ortalıktan kaybolup,tatile gidebilecek kadar vurdumduymazsınız.Yazılım ekibi sorumlusu olarak,sürekli takım çalışmasının öneminden bahsedip,yapılması,yetişmesi gereken, önemli işlerde bir katkınız olmadığı gibi forum,blog ve sosyal paylaşım sitelerinde lüzumsuz konularla tartışıp,yazışarak vakit harcıyorsanız.
  • Yanlış davranış ve anlaşmazlıktan kaynaklanan durumlarda,tazminat ödememek için mobbing uygulayarak yazılımcının işi kendisinin bırakması için elinizden geleni yapıyorsanız. 
  • Çalışanınıza karşı dürüst olmayıp,kendize karşı dürüst olmasını bekliyorsanız. 
  • “Burada Kimse Vazgeçilmez” gibi cümleler kurup vazgeçilmez olduğunu hatırlatıyorsanız.

  • Beyniyle çalışan üreten yazılımcıyı salak yerine koyuyorsanız.
  • Projede çalışan yazılımcılar,önemli işleri yetiştirmeye çalışırken,bunları önemsemeyip,siz proje lideri olarak,çalıştığınız kurumda kıdem mevki yükseltmek için,üniversite sınavına çalışıyor ve liselilerle birlikte,üniversite sınavına giriyorsanız.
  • Yazılımcıya yalan söylerek,anlattığınız takım çalışmasını uygulamıyorsanız.
  • Yeni mezun yada proje liderliği yapamayacak yazılımcıyı kandırarak,seni  “proje lideri” olarak düşünüyoruz diye kandırıp,hiç alakası olmayan işler ile uğraştırırsanız.
  • Yazılımcıların beyni ile çalıştığını hala idrak edemediğiniz gibi,ofisteki gürültülü,sesli çalışma ortamına çözüm üretmek yerine,yazılımcının gürültüden kendini soyutlayarak,daha iyi adapte olabilmek için kulağına taktığı kulaklığa,iş yerinde kulaklık takılmaz,ben hiç takmıyorum gibi bir cevap veriyorsanız.
  • Yönetici olarak, yazılımcı ile aranızda ki olan anlaşmazlıkları,oturup konuşarak çözemeyecek kadar asosyal ve iletişim yoksunu olup,yazılımcının arkasından konuşmayı tercih ediyorsanız.
  • Asıl işi yazılım geliştirmek olan yazılımcıyı,aynı zamanda teknik destek işinde kullanıp,yazılımcının yeteneklerini köreltip,öğrenme hevesini kaçırdıktan sonra “kendini geliştirmiyorsun” şeklinde uyarda bulunabiliyorsanız.
  • Müşteri sayısının arttığı,az personelle iş yürütüldüğü bir grafikte,”gelirler azalıyor,giderler artıyor” gibi konuşmalar yapıyorsanız.
  • Personelin sigortasını asgari ücretten gösterip,cuma namazını kaçırmıyorsanız.
  • Bloğunuzda ayet,hadislerden notlar paylaşıp,mevlanın “Ya olduğun gibi görün,ya da göründüğün gibi ol” sözünü idrak edememişseniz.
  • Yazılımcı yada müşterinin fikir ve önerilerini umursamayıp,kendi fikir ve düşüncelerinizi dikte edecek kadar egolu iseniz.
  • İyi bir şey yapıldığında “biz yaptık” deyip,kötü bir durumda,yazılımcıyı günah keçisi olarak ilan edebiliyorsanız.
  • Kendi yaptığınız veya yapmadığınız şeyleri,yazılımcıya niye uymuyorsun gibi,tıpkı bir sarhoşun elinde ki içki şişesinden bir yudum çekerek,alkol kötü bir şey durumuna benzer bir uyarıda bulunuyorsanız.
  • Sizi ilgilendirmediği halde, yazılımcının sosyal ağlarda ki paylaşımlarını takip edip,eleştiriyorsanız.

    Yukarıda ki durumlarda bir yazılımcıya,piyasada ki en iyi ücreti bile verseniz sizinle çalışmayacağı kesindir.
    Evet belki yıllardır bu sektörden bir şekilde para kazanıyor/kazanmış olabilirseniz.Fakat bu şekilde elde ettiğiniz kazanç esnasında,kaybettiğiniz insan sayısıda doğru orantılı şekilde artacaktır.

    Genelde sorunlar ortak,fakat bu sorunlar en temeline inildiğinde,şahsi menfaatin olduğu,bu menfaati sağlarken de,insanın harcandığını ve zerre miktarda önemsenmediğini görmek mümkündür.

    Şahsi menfaat bir nebze olsun,hoşgörüyle,iyi niyetle belki karşılanabilir.Fakat insanın harcanması yada önemsenmemesine kimse izin vermez.

    Bu yazı kesinlikle yazılımcıların sütten çıkmış akkaşık olduklarını ifade etmez.Yazılımcı personelin,yöneticinin herkesin bilinçli yada bilinçsiz yaptığı hatalar olabilir.

    Bilinçsiz yapılan hatalarda bir yere kadar,hoşgörüyle iyi niyetle karşılanabilir belki.Ama bilinçli olarak yapılan,ve tekrar edilen hataları kimsen iyi niyetle karşılamaz.


    Eğer birşeyler değişmişyorsa,yazılımcı işten ayrılır,orayı terk eder.

    Bu konuda yazılmış diğer yazılara gözatabilirsiniz.
    500 Beygir Gücünün Hazin Sonu
    Bir Yazılımcı Şirketten Neden Ayrılır?

2 Nisan 2014 Çarşamba

Android Custom Toast Messages


Android uygulamalarında ki standart toast mesajlarını nasıl özelleştirebileceğinizi gösteren bir örnek hazırladım.

Bu örneğe ve detaylı bilgiye 
Android-Custom-Toast adresinden ulaşabilirsiniz...

iyi çalışmalar...

21 Ekim 2013 Pazartesi

Refactoring:Tip Kodlarını Alt Sınıflarla Değiştirin !

Yazılımın domain katmanı tasarlanırken,gerçek hayattaki nesneleri, sınıflar yardımı modellediğimiz aşikardır.
Yanlış bir tasarım/modelleme yapıldığında,düzeltmesi yeniden yapılandırması güçleşir.

Sistematik düşünüp kod geliştirme işini, bir çok dinozor yazılımcı angarya,zaman kaybı olarak algılar.Halbu ki ileri de daha fazla zaman kaybedeceğinin farkında değildir...


Şimdi aşağıda ki örneği inceleyecek olursak;
Bir firmadaki Personelleri görevlerine göre modelleğimiz bir örnek.
Firmada ki personeller görevlerine göre yazılım geliştirici,satışcı,destekçi,müdür gibi farklı görevleri olan personeller var.

Bu personellerin hepsini bir Person sınıfı ile ifade etmek karışıklığa yol açabilir.
Neden derseniz ?
Çünkü her bir personel tipinin temelde bazı özellikleri aynı olsa da,farklı olan özellikleri de olabileceği için tek bir Personel sınıfı ile ifade etmek yanlış,yetersiz,karmaşık ve gereksiz olacaktır. :)

Her ne kadar PersonType gibi bir enum kullanarak, Person sınıfı ayırt etmeye çalışsak da buda yetersiz kalacaktır.

Karmaşıklığa bir örnek verecek olursak;
Aşağıdaki methodları Person sınıfına eklediğimizi düşünelim.
public void kodGelistir(); -> Yazılımcının işidir. 
public void satisYap();    ->  Satışcının işidir.
Bu methodların implementasyonu başarılı bir şekilde çalışsa da mantıken Person sınıfında olması yanlıştır.Person sınıfını gereksiz yere kalabalık eder....

O sebeble public void kodGelistir(); methodunun Developer sınıfına eklememiz gerekir.
Aynı şekilde public void satisYap();  methodunun da Salesman sınıfına eklememiz gerekir.
Bu şekilde yazılımcı Personel den satış yapmasını,satışcı personelden de kod geliştirmesini beklememiş olursunuz ! ;)

Buraya kadar yaptığımız işleme "Replace Type Code with Subclasses" refactoring prensibi deniliyor...

Person.cs
using System;

public enum PersonType
{
    DEVELOPER = 1,
    SALESMAN = 2,
    MANAGER = 3,
    SUPPORTER = 4
}

public abstract class Person
{
    public int id { get; set; }
    public string firstName { get; set; }
    public string lastName { get; set; }
    public double salary { get; set; }

    public PersonType personType { get; set; }

    public Person(PersonType type)
    {
        this.personType = type;
    }

    public static Type getType()
    {
        return typeof(Person);
    }
}

Developer.cs
using System;

public class Developer : Person
{
    public Developer()
        : base(PersonType.DEVELOPER)
    {
        this.salary = 10.000;
    }

    public static Type getType()
    {
        return typeof(Developer);
    }
}

Manager.cs
using System;

public class Manager : Person
{
    public Manager()
        : base(PersonType.MANAGER)
    {
        this.salary = 1500;
    }

    public static Type getType()
    {
        return typeof(Manager);
    }
}

Salesman.cs
using System;

public class Salesman : Person
{
    public Salesman()
        : base(PersonType.SALESMAN)
    {
        this.salary = 1500;
    }

    public static Type getType()
    {
        return typeof(Salesman);
    }
}

Supporter.cs
using System;

public class Supporter : Person
{
    public Supporter()
        : base(PersonType.SUPPORTER)
    {
        this.salary = 1000;
    }

    public static Type getType()
    {
        return typeof(Supporter);
    }
}

Diğer bir mevzu ise yazılan kodda ki iç içe bloklu yapılardır.Bu örnek olduğu için göze okunabilir gözükse de complex bir sistemde ne demek istediğimi çok iyi anlayacaksınız.

Aşağıdaki PersonFactory sınıfına ait iki adet method bulunmakta bunlar ;
public Person cleanCreate(PersonType personType); // factory method
public Person dirtyCreate(PersonType personType); // factory method

İki method da parametre ile verilen enum tipinden, ilgili tipi create edip döndürüyor.

dirtyCreate methodu içersinde switch(condition) yapısı kullanılarak ilgili enum tipinden,
enuma karşılık gelen sınıftan bir intance oluşturuluyor.

cleanCreate methodu içersinde ise map'leme yöntemi ile,ilgili enum tipinden class tipini bulup activator sınıfı ile tipden bir instance oluşturuluyor.

cleanCreate methodu içersinde herhangi bir condition(if,switch vs) kullanmadan map'leme yöntemi ile nesne oluşturma işine de "Replacing Conditionals With Map" işlemi deniliyor.


PersonFactory.cs
using System;
using System.Collections.Generic;

public class PersonFactory
{
    private static object _lock = new object();

    private static PersonFactory instance;

    private static Dictionary map = new Dictionary();

    private PersonFactory()
    {
        this.initializeMap();
    }


    public static PersonFactory getInstance()
    {
        if (instanceIsNull())
            createInstance();
        return instance;
    }

    private static void createInstance()
    {
        lock (_lock)
        {
            if (instanceIsNull())
                instance = new PersonFactory();
        }
    }

    private static bool instanceIsNull()
    {
        return instance == null;
    }

 // Replace Conditional With Map işlemi.
    private void initializeMap()
    {
        map.Add(PersonType.DEVELOPER, Developer.getType());
        map.Add(PersonType.SALESMAN, Salesman.getType());
        map.Add(PersonType.MANAGER, Manager.getType());
        map.Add(PersonType.SUPPORTER, Supporter.getType());
    }


    // iyi bir factory method yazım şekli...
    public Person cleanCreate(PersonType personType)
    {
        Type type;
        map.TryGetValue(personType, out type);
        object instance = Activator.CreateInstance(type);
        return (Person)instance;
    }

    // kötü bir factory method yazım şekli...
    // aşağıdaki swicth yapısındaki şartlı instance oluşturma işlemi,
    // initializeMap methodu içerinde map'leme yöntemi ile değiştirilmiştir.
    public Person dirtyCreate(PersonType personType)
    {
        Person person = null;
        switch (personType)
        {
            case PersonType.DEVELOPER:
                person = new Developer();
                break;
            case PersonType.SALESMAN:
                person = new Salesman();
                break;
            case PersonType.MANAGER:
                person = new Manager();
                break;
        }
        return person;
    }
}

Test sınıfına bakacak olursak ;
PersonFactoryTest.cs
using System;
using System.Text;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;


[TestClass]
public class PersonFactoryTest
{
    private PersonFactory factory;

    [TestInitialize]
    public void init()
    {
        factory = PersonFactory.getInstance();
    }

    [TestMethod]
    public void createDeveloperTest()
    {
        //Yazılımcıda bir personeldir (!)
        Person person1 = factory.cleanCreate(PersonType.DEVELOPER);
        person1.id = 1;
        person1.firstName = "ismail";
        person1.lastName = "Kocacan";
    }


    [TestMethod]
    public void createManagerTest()
    {
        //Müdür de bir personeldir...
        Person person2 = factory.cleanCreate(PersonType.MANAGER);
        person2.id = 2;
        person2.firstName = "ali veli";
        person2.lastName = "deli";
    }


    [TestMethod]
    public void createSalesmanTest()
    {
        //Satışcıda bir personeldir...
        Person person3 = factory.cleanCreate(PersonType.SALESMAN);
        person3.id = 3;
        person3.firstName = "adı lazım değil";
        person3.lastName = "sanane";
    }



    [TestMethod]
    public void createSupporterTest()
    {
        // Destekçide bir personeldir...
        Person person4 = factory.cleanCreate(PersonType.SUPPORTER);
        person4.id = 4;
        person4.firstName = "kezban1";
        person4.lastName = "kezban1";
    }


    [TestCleanup]
    public void finalize()
    {
        factory = null;
    }
}

iyi çalışmalar

20 Ekim 2013 Pazar

100 MetreKare DoğalGazlı Daire Bedava

Balıkesir de maltepe mahallesi civalarından, eve doğru giderken birkaç direkte bu ilanı gördüm.

15 Eylül 2013 Pazar

Entity Framework CRUD

Entity Framework kullanarak bir Kullanici sınıfı üzerinde CRUD işlemlerini gösteren örnektir.
"Code First" tekniği kullanılarak hazırlanmıştır.

Aşağıdaki adresten depoya erişip inceleyebilirsiniz.
Entity Framework CRUD

Tüm bu orm'lerin temelinde reflection kavramının yattığını bilmeyen,ama entity framework uçar kaçar diyen de bir o kadar adama rast gelmişimdir zaman içinde... ;)
Neyse...

iyi çalışmalar.




2 Eylül 2013 Pazartesi

Rtti Gevşek Unitler :)

Bir projedeki unit'lerin uses bloglarına baktığımızda bir sürü unit ismi görürüz.

Bunların bir çoğu da projeye bizim eklediğimiz unit dosyalarıdır.

Ve hepsi birbirine bağlıdır.Bu bağımlığı en aza indirmenin yollarından birisi de ,reflection kullanmaktır. :)

Aşağıda yazacağım rttiFormActivator methodu ile bir "unitismi.formsınıfadı" vererek formu oluşturmak için kullanabiliriz.

Bu method kullanıma göre özelleştirebilir.

function  rttiFormActivator(typeQualifiedName : string; isModal:Boolean=false) : TValue;
var
 context      : TRttiContext;
 rttTyp       : TRttiType;
 instanceType : TRttiInstanceType;
 instance     : TValue;
begin

 try
   context   := TRttiContext.Create();
   rttTyp    := context.FindType(typeQualifiedName);

   instanceType := rttTyp.AsInstance;
   instance     := instanceType.GetMethod('Create').Invoke(instanceType.MetaclassType,[nil]) ;

   Result := instance;

   case isModal of
      true  :   instanceType.GetMethod('ShowModal').Invoke(instance,[]);
      false :   instanceType.GetMethod('Show').Invoke(instance,[]);
   end;

 except on E: Exception do
   raise Exception.Create(typeQualifiedName+ ' Tipi register edilmemiş !');
 end;

end;
Unit1.pas dosyanın uses bloğuna kullanmak istediğimiz herhangi bir unit içersindeki formun unitini tanımlamadan direk aşağıdaki kullanılabilecektir.
procedure TForm1.btnShowForm2Click(Sender: TObject);
begin
  rttiFormActivator('Unit2.TForm2',true);
end;


procedure TForm1.btnShowForm3Click(Sender: TObject);
begin
  rttiFormActivator('Unit3.TForm3');
end;
unit1.pas'ın uses bloğuna unit2,unit3 eklemeyerek,bu unitlere bağlı olmasını engellemiş ve dinamik bir kullanım elde etmiş olduk. Yanlız şöyle önemli bir durum var. Kullanacağınız sınıflarını register etmediğiniz zaman rtti amca findType methodu ile ilgili verdiğiniz tipi bulamıyor. o yüzden sınıfları bulunduğu unit içinde register ederek,findType methodu ile bulmasını sağlayabiliriz.
initialization
 RegisterClass(TForm2);

finalization
 UnRegisterClass(TForm2);


Kaynak Kod : https://github.com/ismailkocacan/Rtti-Loose-Coupling-Units

iyi çalışmalar.

25 Ağustos 2013 Pazar

Unity Dependency Injection And Inversion Of Control

Uzun zamandır "Dependency Injection and Inversion Of Control" konusunda bir çok kaynak okudum.

Esnek tasarlama,esnek kod geliştirme, sınıfların birbirleri olan bağımlıklarının en aza indirgenmesi vs kulağa hoş geliyordu.Lakin anlatılanlarla gördüğüm örneklerin uyuşmaması sonrasında,olm ismail sen bir örnek proje hazırla,koy bir yere dursun hem millete faydan olsun,hem de lazım oldukça kendinde öğrenirsin dedim kendime... :)

Hangi konuda olursa olsun,bir çok şey ihtiyaç üzerine gelişiyor ve var oluyor.
Bu durum yazılım dünyasında frameworklerde de böyle işte.
Peki bu frameworkler neden çıkmış olabilir acaba ?
Herifin birinin işi,gücü yokmuşta dur şu frameworkü yazayım millette kullansın mı demiş ? Tabi ki hayır...

Dependency Injection(Bağımlıkların Enjekte Edilmesi)

Bakalım Neden Çıkmış :)
Zaman içersinde develer tellal iken,pireler berber iken ,yazılımcıların  çalıştığı projelerde sürekli değişiklik olurmuş.Bu değişiklikleri ne istediği belli olmayan,ama hep ne istediğini bilmeyen müşteriler sebeb olurmuş.Bu değişikler sonucunda projedeki kodlar,çarşafçılarda ki çarşaflardan daha karışık bir hal alır ve yönetimi,bakımı,zorlaşırmış...

Yapılan değişikliker sonrasında,projenin akla bile gelmeyen yerleri etkilenir ve hatalı çalışmasına neden olurmuş.Çünkü yazılımcıların yazdığı sınıflar birbirine gönülden bağlıymış.
Onları birbirinden ayırmak mümkün değilmiş(!)...
Mevcut bir sınıfı alıp,düzeltip elden geçirmeden başka bir projede kullanmak bile mümkün değilmiş...
Çıkış nedenlerinden birisi buydu :)

Inversion Of Control(Kontrolün Tersine Çevrilmesi)

Diğeri ise yazılımda nesne oluşturmak,oluşturulan bu nesnenin takibini yapmak ise yine zor bir iştir.Nerde oluşturdum. Nerde bellekten sildim.Veya bir başka methodun benim oluşturduğum nesneyi silmesi vs...

Hal böyle olunca isyan bayrağını çekip,ulan nesne oluşturmak benim işim mi ?
Sorusunu soruyorsunuz kendize...
Misal ; Lokantaya gidip yiyeceğiniz yemeği kendiniz mi yapıyorsunuz ? Hayır.
Olm şşt bak bakem buraya şipariş vericez diyorsunuz.Ne yemek istediğinizi söylüyorsunuz oda getiriyor.

Yani yiyeceğiniz yemeğin(nesne) çeşidini(tipini),adını söylüyorsunuz o da size yemeği create ettirip getiyor.Yemeğinizi yiyip(nesneyi kullanıp) gidiyorsunuz.Nereye gidiyorsunuz olm önce hesabı ödeyin :)
2. nedeni de budur.

Yani nesne create etme kontrolünün bizden alınarak bu işin framework tarafından yapılması kısmına da inversion of control deniyor.
Yani lokantada yiyeceğimiz yemeğin tipini söyleyip,yiyeceğimiz yemeği istiyoruz.

Şimdi bu kadar hikayeden sonra bağımlıkların enjeksiyonu, kontrolün tersine çevrilmesi işi c# da unity ile nasıl oluyormuş ona bakalım.

Unity için framework için gerekli paketi aşağıdaki gibi kurabilirsiniz.


Gelen pencereden unity yazdıktan sonra ;


Bende kurulu olduğu için install butonu gözükmüyor.
Sizde kurulu değilse "install" butonuna tıklayarak kurabilirsiniz.

indireceğiniz örnekte 3 adet proje bulunmakta.

UnitySample : Domain ile ilgili sınıfların bulunduğu proje

UnitySampleUnitTest : Unit Test Projesi.

UnityWindowsFormApplication : windows form örnek uygulamasıdır.

Stock klasöründe StockCard ve StokCategory sınıfları bulunmakta.Eğer projemizde ki  stok kartlarını,kategorileyecek olursak,böyle bir tasarım yeterlik olacaktır.

Yani burdan şunu anlıyoruz ki ;
Her stok kartının, birde stok kategorisi olacak.
Stok kategorisine ait birden fazla özellik olabileceği için de StockCategory isminde ayrı bir sınıfta topladık.

Yani her StockCard sınıfın içersinde,birde StockCategory tipinde bir nesne olması gerekli değil mi ?

    // stok kategori sınıfı
    public class StockCategory : IStockCategory
    {
        public int id { get; set; }
        public string categoryName { get; set; }
        public DateTime insertionTime { get; set; }
    }
 
   // Stok Kartı sınıfımız
    public class StockCard : IStockCard
    {
        public int id { get; set; }
        public string stockCode { get; set; }
        public string stockName { get; set; }
        public double unitPrice { get; set; }
        public double amount { get; set; }
        public double total { get; set; }
        public DateTime insertionTime { get; set; }


        public StockCategory stockCategory { get; set; }


        public StockCard()
        {

        }
    }
Peki direk olarak StockCard sınıfa StockCategory tipinde bir property eklersek ne olur ? StockCard sınıfı,StockCategory sınıfına gönülden bağlı olur. StockCategory sınıfının ismini değiştirdiğimde,veya projeden sildiğimde derlemez bile... Sınıfın kendini yazmak yerine,O sınıfın implement ettiği interface tipinizi(IStockCategory) yazıyoruz. Böylece StockCategory sınıfını projeden silinse veya ismi değişse bile derlemede problem çıkmayacak. Sırf derlemede problem çıkmasın diye mi böyle yazdık ? Hayır. Neden ?
    public interface IStockCategory
    {
        int id { get; set; }
        string categoryName { get; set; }
        DateTime insertionTime { get; set; }
    }


    // stok kategori sınıfı
    public class StockCategory : IStockCategory
    {
        public int id { get; set; }
        public string categoryName { get; set; }
        public DateTime insertionTime { get; set; }
    }
 
 
 
    public interface IStockCard
    {
        int id { get; set; }
        string stockCode { get; set; }
        string stockName { get; set; }
        double unitPrice { get; set; }
        double amount { get; set; }
        double total { get; set; }
        DateTime insertionTime { get; set; }

        [Dependency("stokCategory")]
        IStockCategory stockCategory { get; set; }
    }


    // Stok Kartı sınıfımız
    public class StockCard : IStockCard
    {
        public int id { get; set; }
        public string stockCode { get; set; }
        public string stockName { get; set; }
        public double unitPrice { get; set; }
        public double amount { get; set; }
        public double total { get; set; }
        public DateTime insertionTime { get; set; }

        public IStockCategory stockCategory { get; set; }


        public StockCard()
        {

        }
    }
Eğer StockCard sınıfına yazacağımız property aşağıdaki gibi yazılmış olursa;
 public IStockCategory stockCategory { get; set; }
IStockCategory sınıfını implement eden her türlü sınıf tipindeki değişken ,stockCategory propertisine atanabilir. alsana esneklik :D Buraya kadar sadece interface'lerle esnek bir tasarım ve modelleme yaptık.

Şimdi geldik zurnanın deliğinin zırt dediği yere !

Bu oluşturduğumuz tiplerleri UnityContainer sınıfının register methodları ile sınıfların meta bilgilerini kayıt ettirip ilgili map'lemeleri en başta bir kere yapıyoruz.

Daha sonra bir nesne lazım olduğu zaman,UnityContainer sınıfından şu tipte bir nesne lazım dedikten sonra istediğimiz nesneyi elde ediyoruz.

ContainerManager sınıfımız aşağıdaki gibi.
using Microsoft.Practices.Unity;

public class ContainerManager
{
    private static UnityContainer container = new UnityContainer();

    public static UnityContainer getContainer()
    {
        return container;
    }
}

Initialization sınıfımız.
using Microsoft.Practices.Unity;
using UnitySample;

public class Initialization
{
    public static void registerObjects()
    {
        UnityContainer container = ContainerManager.getContainer();
        container.RegisterType();

        // StockCard sınıfının,stockCategory property değeri dinamik olarak set ediliyor.
        var injectMember = new InjectionProperty("stockCategory", container.Resolve());
        container.RegisterType(injectMember);
    }
}
Initialization.registerObjects(); ile önce meta bilgileri register edeceğiz. Burada dikkat etmemiz gereken injection olayının(property injection) yapıldığı yerdir.
        // StockCard sınıfının,stockCategory property değeri dinamik olarak set ediliyor.
        var injectMember = new InjectionProperty("stockCategory", container.Resolve());
        container.RegisterType(injectMember);
Görüldüğü üzere dinamik olarak,StockCard sınıfının stockCategory propertiesi set ediliyor. Yani stockCard nesnesini kullanırken ;
  stockCard.stockCategory = new StockCategory();
  stockCard.stockCategory.categoryName = "Beyaz Eşya"; 
yukarıdaki gibi nesne oluşturmanıza gerek kalmayacak.Direk olarak aşağıdaki gibi kullanabileceksiniz.
  stockCard.stockCategory.categoryName = "Beyaz Eşya"; 
Çünkü daha önce containere eklerken,gerekli map'leri yaparak ekledik.Biz yapacağımız işi en başta bir gerek yaptık yani !

Şimdi Artık Herşey Hazır Bir Test Sürüşüne Çıkalım :)

using System;
using Microsoft.Practices.Unity;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using UnitySample;

namespace UnitySampleUnitTest
{
    [TestClass]
    public class StockCardTest
    {

        UnityContainer um;

        [TestInitialize]
        public void testInitialize()
        {
         // sınıfların meta bilgilerini container'a ekleyen methodu çağırıyoruz.
           Initialization.registerObjects();
           um = ContainerManager.getContainer();
        }
         

        [TestMethod]
        public void stokKartiNesnesiOlustur()
        {
            if (!um.IsRegistered())
                throw new Exception("stok kartı register edilmemiş.");

            // bir tane stok kartı nesnesi oluştuyoruz.
            var stockCard = um.Resolve();
            // veya aşağıdaki şekilde de containerdan objecte erişmek mümkün.
            //var stockCard = this.getDIContainer().Resolve();
            stockCard.stockCode = "ST0001";
            stockCard.stockName = "Buzdolabı";
            stockCard.insertionTime = DateTime.Now;
            stockCard.unitPrice = 2500;
            stockCard.amount = 60;

            stockCard.stockCategory.categoryName = "Beyaz Eşya";
            stockCard.stockCategory.id = 1;
            stockCard.stockCategory.insertionTime = DateTime.Now;
        }
    }
}
Bu tip kütüphanelerin temelinde reflection kavramının yattığını bilmekte fayda var ;)
Bu Kadar !


Proje kaynak kodu  
https://github.com/ismailkocacan/Unity-Dependency-Injection-And-Inversion-Of-Control

Kaynaklar 

http://unity.codeplex.com/
http://msdn.microsoft.com/en-us/library/ff649614.aspx
http://msdn.microsoft.com/en-us/library/vstudio/bb383977.aspx