Arda Çetinkaya Thoughts on software, with the occasional personal rambling…

Bu haftanın grupları…

/ Leave a comment / ~ 2 dakikada okuyabilirsiniz.

Bu hafta bunları dinlemişim,etmişim…Özellikle IAMX’i ve Deftones’u yedim yuttum…IAMX konseri olduğu için özel ilgi gösterdim hatta…Ama 3 Nisan ki konserden sonra ilginin boşa gitmediğini gördüm sevindim…Son zamanlarda izlediğim en iyi performansı sergiledi IAMX. Umarım tekrar gelirler…Gelmeleri lazım…Deftones’un yeni albüm de şahane…Biraz zor bir albüm aslında, ama biraz sabır ile kolay aşılabilen bir zorluk…Umarım Deftones’u da görürüz yine yakında…

Bugün başlayan ve önümüzdeki 2 gün boyunca devam edecek Mix10 etkinliğinde ilk duyurulan haberler, Silverlight 4’ün “yayın adayı” ve WCF RIA Services’in “yayın adayı” oldu. Nisan ayı gibi de sanırım bu iki kavramın son hallerine kavuşuyor olacağız…Ayrıntılı bilgileri ve indirmek için gerekli linkleri aşağıdaki adreste bulabilirsiniz.

http://www.silverlight.net/getstarted/silverlight-4/

Bir güzel ve önemli haber ise Windows Phone 7’den…Windows Phone 7’nin geliştirici araçları da bugün itibari ile geliştiricilere sunuldu. Tabi telefon çıkmadan pek kullağa mantıklı gelmiyor ama geliştirme ortamının sağladığı güzellikler ile ilgileniyorsanız hemen olaya dalmanızı tavsiye ederim.Daha fazla ayrıntı ve geliştirme araçları için aşağıdaki linki takip edebilirsiniz.

http://developer.windowsphone.com/windows-phone-7-series/

Bir yazılım projesinde yazılım tasarımına başlarken, kafamızda ilk yaptığımız şey genellikle direk projenin nesne modelini çıkarmaya çalışmak oluyor. Yanlış bir şey olmasa da öncesinde yapılması gereken başka şeyler olduğundan ortaya çıkan nesne modeli ne kadar sağlıklı oluyor tartışılır. Kendi tecrübelerim ve gözlemlerime göre genellikle nesnelerin bir birleri ile ilişkilendirilmeleri konusunda hatalar yapabiliyoruz. Aslında hata demek doğru olmaz. Bazı noktaları düşünmeden, bazı şeyleri göz ardı ederek nesne modellerini oluşturuyoruz ve bunlar yazılım tasarımının ilerleyen aşamalarında sorun olarak karşımıza çıkmasa da, geliştirme sürecinde mutlaka karşımıza çıkıyor. Nesnelerin bir birleri ile olan ilişikileri ile bir sonraki yazımda daha çok ilgileniyor olacağım. Ama önce nesnelerimizi tasarlarken göz ardı edildiğini düşündüğüm bir kaç noktaya değinmek istiyorum.

Bir nesnenin var oluş sebebi…

Her hangi bir kavramın nesne modelini oluştururken, o kavramın ne amaçla var olduğunu asla unutmamak gerekir. Gerçekleştireceği operasyonların, o kavram dahilinde olduğunu kesinleştirmek nesne modelini ve ilgilerini oluşturmakta daha kolaylık sağlayacaktır. Matemetikte ki 4 işlemi soyutlayan bir nesneye, belli bir süre için faiz hesaplayan bir metodu da 4 işlem dahilinde olduğunu düşünerek eklemek o nesnenin karmaşıklığını artıracaktır. Farklı yerlerde farklı şekillerde var olabileceğinden tasarımsal olarak soruna yol açacaktır. Dolayısıyla nesnelerin görevlerinin çok net bir şekilde tanımlanıyor olması gerekmekte.

Bir nesnenin yaşam süresi…

Nesnelerin, bütün içerisinde ki yaşam süresini yönetebiliyor olmak çok önemlidir. Gelişen “geliştirme teknolojileri” bu sürenin yönetimini biraz olsun geliştiriciden alıyor olsa da, en azından nesnelerin yaşam sürelerinin farkında olmak bizim için çok önemli. “Object reference not set to an instance of an object”(sanırım en çok alınan hatadır) hatasını alıyor olmamız, bir bakıma da nesnelerimizin nerede, ne zaman, nasıl yaşadığının farkında olmamamızdan kaynaklanıyor diyebilirim. Nesnelerimizin, nerede, ne şekilde, ne kadar yaşayacağını ya da var olacağını çok iyi belirlememiz gerekiyor.

Bir nesnenin ilişkileri…

Nesnelerin bir birleri ile olan ilişkilerini ortaya net bir şekilde çıkarmak çok önemlidir. Bu noktada “Composition(part-of)”(Bileşim),“Aggregation(has-a)”(Kümelenme,bir araya gelme) ve “Inheritance(is-a)”(Kalıtım) kavramlarını anlıyor olmak çok önemlidir. Teorik olarak kavramlara hakim olsak bile, nesne tasarımlarında bunları uygulama konusunda zaman zaman sıkıntı çekilebiliyor. Nesneler arasında ki ilişikleri, hangi nesnenin hangi nesneye bağlı olduğunu ya da olacağını ilk başlarda kestirebiliyor olmak çok zor olsada,  bu zorluğa katlanıp çözme çabası olumlu sonuçları beraberinde getirecektir. Bu aşamada “Dependency injection”, “Inversion of control” kavramlarını da çok iyi anlıyor olmamız gerekmekte…
Bu üç başlığın yazılım tasarımı konusunda, özellikle nesne modeli oluştururken çok önemli olduğunu düşünüyorum. Şimdilik bu kadar…

Asp.Net MVC Framework 2 versiyonu yayınlandı. Ama şu an için sadece Visual Studio 2008 için…Buradan indirebilirsiniz.Önümüzdeki günlerde Visual Studio 2010 için olan versiyonu da ortaya çıkacaktır diye umuyorum. Bildiğiniz gibi Asp.Net MVC 2, önceki sürümle beraber(Asp.Net MVC 1) ile aynı geliştirme ortamında çalışabiliyordu. Bu hala devam etmekte. Öte yandan eski Asp.Net MVC 1 projelerini MVC 2’ye geçirmek isterseniz de Visual Studio 2008 için http://www.asp.net/learn/whitepapers/aspnet-mvc2-upgrade-notes/ adresindeki upgrade notlarını okuyabilirsiniz. Visual Studio 2010 için bu upgrade olayı bir sihirbaz ile kolayca gerçekleşebilecek.Hokus,pokus…(:

2008’de Microsoft “MEF” yani Managed Extensibility Framework isimli yeni bir framework üzerinde çalıştığını açıklamıştı.  Basitçe, biz geliştiricilere, “plug-in” yapısını destekleyen uygulamalar geliştirmemiz için yöntemler sunan bir framework diyebiliriz “MEF” için.

.NET Framework 4.0’a kadar, Microsoft, .NET’in içine koymuyor, “preview” adı altında sürekli geliştirmeler yapıyordu. .NET 4.0 ile beraber artık “MEF”i gönül rahatlığı ile kullanabiliyor olacağız.

Bu kısa girişten sonra, biraz daha derinlere inelim ve “MEF”in bize neler sağladığına ve neden kullanmamız gerektiğine bakalım. Öncelike “MEF” gibi bir framework’e neden ihtiyacımız var bunu anlamamız lazım. Tekrar kullanılabilirlik(Reusability) ve esneklik(extensibility), bir yazılımın yaşam sürecinde mutlaka bir şekilde karşımıza çıkan iki kavram. Geliştirdiğimiz yazılımlar çeşitli ihtiyaçlardan dolayı, ek özellikler ile genişletilmek istenebilir. Ya da geliştirdiğimiz yazılımı başka bir konfigürasyon ya da modüller ile başka bir şekilde kullanmamız da gerekebilir. Bu iki kavramı yazılımlara uygulamak oldukça zor ve sıkıntılıdır. Hele ki mimari tasarım sırasında bu iki kavramı göz ardı ettiysek sıkıntı çok daha büyük olur. Tabi ki bir yazılım illa ki esnek ya da tekrar kullanılabilir özelliğinin olması gerekmiyor. Ancak kişisel görüşüm, yazılımın yaşam süresinin uzun olabilmesi için bu iki kavramı karşılayabiliyor olması gerekmekte.

Esneklik ve tekrar kullanılabilirlik özelliklerine sahip bir yazılım ihtiyacı çok iyi bir tasarım gerektirir. Tasarımdan sonra ki geliştirme sürecini de bu iki kavram oldukça zorlar. Bu noktada “MEF”, .NET ile uygulama geliştirenlere bu süreci biraz daha kolaylaştırmak için elinden geleni yapıyor diyebilirim.

Bir PC’yi düşünelim…Anakartı ve bu kartın üzerine takılabilen ek kartlar ile çalışabilir bir sistem…X ekran kartı ile oynayamadığımız oyunları, X ekran kartını çıkartıp, Y ekran kartını takarak oynayabiliyoruz.Bunu ekran kartlarının, anakart ile belli bir arayüz standartı ile iletişim kurabilmesinden dolayı yapabiliyoruz.

“MEF” ile de bu tarz,“plug-in” yaklaşımı olan uygulamalar geliştirebiliyoruz. Run-time’da çıkarılıp, takılabilen “plug-in”ler ile uygulamalarımızı genişletebiliyoruz. Ve bütün bunlar System.ComponentModel.Composition.dll altında bulunan metod ve arayüzler sayesinde…

Kod üzerinden gidip ilk “MEF” uygulamamızı yaparsak sanırım bazı şeyler daha anlaşılır olur.Az önce yukarıda bahsetmiş olduğum PC örneği üzerinden gidiyor olacağım. Öncelikle aşağıdaki gibi 3 tane proje yaratıyoruz. Bunlardan biri ana uygulamamız(CustomPC,konsol uygulaması), biri arayüzümüz(DisplayAdapter) ve diğeri de ana kartımız(Xvidia). (:

Bu aşamada CustomPC ve XVidia projelerine System.ComponentModel.Composition.dll’i referans olarak eklememiz gerekmekte.

Öncelikle ana uygulamamız ve ekran kartımızın iletişim kuracağı arayüzümüzü oluşturalım. DisplayAdapter projesinde IDisplay.cs isimli aşağıdaki kodu içeren bir dosya yaratıyoruz;

46 using System;

47 using System.Collections.Generic;

48 using System.Linq;

49 using System.Text;

50

51 namespace DisplayAdapter

52 {

53 public interface IDisplayAdapter

54 {

55 void Display();

56 }

57 }

Bu arayüz sayesinde ana uygulamamız, “plug-in” olarak geliştirdiğimiz diğer bileşenleri çalıştırabiliyor olacak. Bundan sonra bu arayüzden yaratılan “plug-in”i geliştirebiliriz. Bir bakıma “ekran kartı”nı…(:

Bunun içinde XVidia projesinde aşağıdaki kodu yazmamız gerekmekte;

58 using System;

59 using System.Collections.Generic;

60 using System.Linq;

61 using System.Text;

62 using System.ComponentModel.Composition;

63

64 namespace DisplayAdapter

65 {

66 [Export(“”,typeof(IDisplayAdapter))]

67 public class XVidiaIDisplayAdapter

68 {

69

70 public void Display()

71 {

72 Console.WriteLine(“This is XVidia Display Adapter”);

73 }

74 }

75 }

Bu noktada “Export” özelliği dikkatimizi çekmiş olmalı. “MEF”‘de “Composable Parts” diye adlandırılan ve “MEF”in temel taşı olan bir kavram var. “Composable Parts” belli servisleri(metod) dışa sunan ve belli servisleride(metod) kullanan birimler. Ana uygulamalar ve “plug-in”ler bu birimlere göre çalışmakta. Yukarıdaki kod bloğunda “Export” özelliğini kullarak, XVidia sınıfını “IDisplayAdapter” arayüzünün metodlarını dışa sunduğunu göstermiş olduk.

Şimdi sıra “plug-in”leri çalıştıracak ana uygulamamıza geldi. Bunun için CustomPC projesinde aşağıdaki kodu içeren bir dosya yaratmamız yeterli.

82 using System;

83 using System.Collections.Generic;

84 using System.Linq;

85 using System.Text;

86 using System.ComponentModel.Composition.Hosting;

87 using System.Reflection;

88 using DisplayAdapter;

89 using System.ComponentModel.Composition;

90

91 namespace CustomPC

92 {

93 public class Computer

94 {

95 //Hangi arayüzün “MEF” tarafından import

96 //edileceğini belirtiyoruz.

97 [Import(typeof(IDisplayAdapter))]

98 public IDisplayAdapter DisplayAdapter { get; set; }

99

100 static void Main(string[] args)

101 {

102 Console.WriteLine(“PC’s configuration”);

103 Computer comp = new Computer();

104 comp.Init();

105

106 Console.ReadLine();

107 }

108

109 public void Init()

110 {

111 try

112 {

113 /*

114 * Plug-in’lerin olduğu yeri belirtmek için “MEF”

115 * ile gelen katalog kavramından faydalanıyoruz.

116 * İlerleyen yazılarda bu katalog kavramının

117 * derinlerine dalıyor olacağım.Şimdilik “plug-in”lerin

118 * bir dizinden okunacağını belirtmek için

119 * DirectoryCatalog sınıfı kullanıyoruz.

120 */

121 DirectoryCatalog dirCat = new DirectoryCatalog(Environment.CurrentDirectory + “\\plugin\\”);

122 /*

123 * “MEF” ile beraber gelen “CompositionBatch” ve

124 * “CompositionContainer” sınıfı ile “is a part of”

125 * ilişkisini kurabileceğimiz yapıyı yaratıyoruz.

126 * “is a part of” ilişkisi derken ne demek istediğimi

127 * açıklamamda fayda var sanırım.”plug-in”‘ler ana

128 * uygulamamızın bir parçası olacak.Ve bu parçalar

129 * takıp,çıkarılabilir özelliklere sahip olacak.

130 * Bütün bu ilişkiler “MEF” tarafından yönetiliyor olacak.

131 * “CompositionBatch” parçaların(Composable Parts)

132 * tutulduğu,”CompositionContainer” ise

133 * parçaların(Composable Parts)’ın metodlarının ve

134 * özelliklerinin sunulmasını sağlayan yapı olarak

135 * tanımlanabilir.

136 */

137 CompositionBatch batch = new CompositionBatch();

138 CompositionContainer container = new CompositionContainer(dirCat);

139

140 //Parçalarımızı ekliyoruz

141 batch.AddPart(this);

142

143 //Parçalarımızı ana uygulama ve birbirleri ile

144 //ilişkilendiriyoruz

145 container.Compose(batch);

146

147 //Parçalarımızı çalıştırıyoruz.Bu noktada

148 //arayüzün(IDisplayAdapter) sunduğu

149 //metodları sunabiliyoruz sadece.

150 DisplayAdapter.Display();

151 }

152 catch (Exception)

153 {

154

155 throw;

156 }

157

158

159 }

160

161

162 }

163

164

165 }

Ve işte bu kadar…Hemen özetliyelim ne yaptık. Bir tane “plug-in” desteği olan ana uygulama yaptık(CustomPC) ve bu ana uygulama üstünde çalışacak bir tane “plug-in” yaptık. Yaptığımız “plug-in” benzeri başka “plug-in”ler yaparak, uygulamamızı çeşitlendirebiliriz. Mesela XTI diye yeni bir ekran kartı, pardon “plug-in”….(:

Yukarıdaki CustomPC projesini çalıştırdığımız zaman hata alıyor olacağız. Peki ama neden? Bunun nedeni “XVidia” projesinin çıktısı olan *.Dll’in ana uygulama tarafına yüklenmemiş olması. CustomPC projesinin dizininde, “debug” klasörü altında “plugin” diye bir klasör açıp, “XVidia” projesinin çıktısı olan *.Dll’i kopyaladığımız zaman uygulamamızın sorunsuz bir şekilde çalıştığını göreceğiz.

“XVidia” projesinin çıktısı olan *.Dll yerine, benzer bir yapı ile oluşturulmuş bir *.Dll koyduğumuz zaman uygulamanın o *.Dll’i çalıştıracağını görüyor olacağız.

Çok basit ve güzel değil mi… .NET 4.0’ın bence en güzel yeniliği “MEF” ile entegre olması…İlerleyen yazılarda “MEF”in çok daha derinlerine dalıyor olacağım…Şimdilik bu kadar…

, ,