Koray Kırdinli

Yazılım ve İş Yaşamı Hakkında Paylaşımlar

MCTS – Application Domain’ler ve Servisler

Application Domain harici assembly’leri efektif ve güvenli bir şekilde çağırmamızı sağlar.Servisler ise kullanıcı arabirimi olmayan ve geri planda çalışan assembly’lerin özel bir halidir.Bu makalemizde application domain’i nasıl konfigüre edebileceğimizi ve servisleri geliştirip nasıl yükleyebileceğimizi göreceğiz.

Application Domain birçok assembly’i tek bir process içerisinde çalıştırmak üzere içinde barındıran mantıksal bir konteynırdır ve direk olarak diğer assemblylere erişimini kısıtlar.

Application Domain’e verilebilecek örnek IIS 5.0 olabilir.Eğer 10 kullanıcı siteyi ziyaret ederse ASP.NET her bir kullanıcı için farklı Application domain oluşturur. Burada aynı assembly 10 farklı kullanıcı için farklı process’lerde çalıştırılıyor ve böylece birbirlerinin içeriklerini ezme durumu ortadan kalkıyor.

.NET’te System.AppDomain sınıfı bu gibi işlemleri yapabilmek için oluşturulmuştur. Aşağıdaki kod parçası ile yeni bir domain oluşturmak mümkün.

AppDomain d = AppDomain.CreateDomain(“Koray’ın Alanı”);

Console.WriteLine(“Host domain:” + AppDomain.CurrentDomain.FriendlyName);

Console.WriteLine(“Child Domain:”+d.FriendlyName);
//Aşağıdaki kod ile domainde bulunan bir assembly’i çalıştırmak mümkün.

d.ExecuteAssembly(“Assembly.exe”);

d.ExecuteAssemblyByName(“Assembly”);
//Domaini serbest bırakmak için

AppDomain.Unload(d);

 

Application domainler özelleştirilebilirler bunu yapmaktaki en önemli amaç izinleri azaltarak güvenlik risklerini düşürmektir. Eğer bunu yapmaz ve Application Domain imize harici assembly yüklersek saldırıya maruz kalabiliriz.

Peki bir assembly’i limitli olarak nasıl Application Domain içinde çalıştırabiliriz. Bunu bir örnekle açıklamak gerekirse ; Şirketiniz 3rd parti bir assembly satın aldı diyelim ve bu assembly veritabanı ile iletişim halinde.Bunu 3rd parti assembly’deki açığı farkeden bir saldırkan bir spyware uygulaması ile güvenlik açığından faydalanabilir çünkü uygulamamız 3rd parti assembly’e tüm kalbilyle güveniyor J.Açık 3rd parti assembly dede olsa bizim sistemimize sızabilirler. Eğer 3rd parti assembly’e limitli erişim (Limited Privileges) hakkı verseydik I/O istekleri reddedilecek ve risk azalacaktı. Defend-in-depth güvenlik prensibine göre harici koda güvemek güvenlik zaafiyetlerine yol açar.
.NET’te assembly haklarını kontrol edebilmek için System.Policy.Evidence nesnesinden faydalanabiliriz. Bu nesnenin ExecuteAssembly metodu Application Domain’in metodunu ezmektedir.

object[] hostEvidence = { newZone(SecurityZone.Internet) };

Evidence appDomainEvidence = newEvidence(hostEvidence, null);

AppDomain d = AppDomain.CreateDomain(“MyDomain”, appDomainEvidence);

d.ExecuteAssembly(“SecondAssembly.exe”);

Mayıs 25, 2010 Posted by | C# | , , , | Yorum bırakın

Threading

Bir uygulama harddiskte çalışmadan durduğu zaman buna program denir, program çalışmaya başladığı zaman rame yüklendiği zaman ise process diye adlandırılır.Bu process’leri ise işleyen bilgisayar arabirimi işlemcidir. Herhangi bir t anında aynı anda birden çok process’in işlenmesine ise multi-tasking adı verilir. İşlemci process’leri küçük threadler halinde sanki anyı anda çalışıyormuş gibi sıraya sokar ve kullanıcya hisettirmeden sırayla çalıştırır.
Threading çoklu işlemleri eşzamanlı olarak işlemeye yarar. Eğer bir uygulamayı tek kanallı olarak programlarsak çok işlemli bir bilgisayarda diğer işlemcileri boşa harcamış oluruz.
.NET’te Threadler ile çalışmaya başlamak için öncelikle Thread sınıfını incelemenin faydalı olacağı kanaatindeyim. Thread aslında bağımsız olarak bir kanalı kullanan küçük kod parçasıdır diyebiliriz ve bu kod parçalarını ; her bir kanalı başlatabilir (Start), durdurabilir(Abort) veya yaşıyor mu(IsAlive) kontrol edebiliriz.
Threadler ile çalışabilmek için
System.Threading namespace’ini using kısmına eklememiz gerekmektedir.

Bir Threadi başlatabilmek için öncelikle ThreadStart delegesi oluşturulur. Bu delege void dönen bir metod parametre alır ve o metodun başlangıç adresini temsil eder.Daha sonra Thread’e parametre olarak ThreadStart delegesi verilir ve Thread başlatılır.

void SimpleWork()

{

MessageBox.Show(String.Format(“Thread {0}”, Thread.CurrentThread.ManagedThreadId));

}

ThreadStart ts = newThreadStart(SimpleWork);

for (int i = 0; i < 5; i++)

{

    Thread t = newThread(ts);

    t.Start();

    Thread.Sleep(1000);

}

Eğer bu uygulamayı thread ile yapmasaydık ManagedThreadId hep aynı olacaktı ancak her seferinde yeni bir thread oluşturduğumuz için farklı id ler elde ediyoruz.

Thread.Abort(): Theadin derhal sonlandırılmasını sağlar.Bu metodu çağırdığımızda ThreadAbortException hatası fırlatılır. Eğer Abort işlemi doğru yerde yakalanırsa bu hata Framework tarafından yakalanır. Bu hataya düşmemek için önemli kodu Thread.BeginCriticalRegion ve Thread.EndCriticalRegion arasına yazmak gerekebilir.

Thread.Join Metodu : Pratikte bir threadi sonlandırmak için kendi içerisinde yaratılan başka bir threadin beklenmesi gerekebilir.Bu gibi durumlarda Join metodu kullanılır.

ThreadStart ts = newThreadStart(SimpleWork);

Thread[] threads = newThread[5];

for (int i = 0; i < 5; ++i)

{

    threads[i] = newThread(ts);

    threads[i].Start();

}

 

foreach (Thread item in threads)

{

    item.Join();

}

Threadlerin öncelikleri ThreadPriority enumarasyonu ile belirleyebiliriz.
Highest,AboveNormal,Normal,BelowNormal,Lowest.

Yukarda anlattığımız gibi ThreadStart delegesi sadece void dönen ve parametre almaayan metodları temsil edebilir.Gerçek hayatta ise parametre alan metodları da temsil etme ihtiyacı duyabiliriz.Bunun için ThreadStart delegesi yerine ParameterizedThreadStart delegesi kullanılır.ParameterizedThreadStart delegesi void dönen ve parametre olarak object alan metodları temsil edebilir.

void WorkWithParameterMetod(object o)

{

    string info = (string)o;

    for (int i = 0; i < 10; ++i)

    {

        Console.WriteLine(“{0} {1}”,info,Thread.CurrentThread.ManagedThreadId);

        Thread.Sleep(10);

    }

}

ParameterizedThreadStart pts = newParameterizedThreadStart(WorkWithParameterMetod);

Thread t = newThread(pts);

t.Priority = ThreadPriority.Highest;

t.Start(“KORAY”);

Thread t2 = newThread(pts);

t2.Start(“KIRDİNLİ”);

Multithreading programlama yaparken programcıyı en fazla zorlayan şeylerin başında farklı threadler arasındaki veri alış verişi gelmektedir. Threadler arasında paylaşılan veriyi güvenli bir şekilde threadler arasında transfer edebilmek önemlidir neyse ki .NET Framework bu işi kolaylaştırıyor.
Aşağıdaki örnekte Counterın 10000 olmasını beklerken threadSayisi*10000 olduğunu göreceğiz.

publicclassCounter

{

    publicstaticint Count;

}
publicvoid UpdateCount()

{

    for (int i = 0; i < 10000; i++)

    {

        Counter.Count += 1;

    }

}

ThreadStart ts = newThreadStart(UpdateCount);

Thread[] threads = newThread[10];

for (int i = 0; i < 10; i++)

{

    threads[i] = newThread(ts);

    threads[i].Start();

}

//Threadlerin bitmesini bekle

for (int i = 0; i < 10; i++)

{

    threads[i].Join();

}

 

Console.WriteLine(“Toplam:{0}”,Counter.Count);
//Eğer bu kodu çok işlemli bir bilgisayarda çalıştırırsanız Sonuç 10000 değil 10000*10=100000; olacaktır.
Bu durumu engellemenin yolu Interlocked sınıfını kullanmaktır.UpdateCount metodunda for döngüsü içine Counter.Count += 1; yerine aşağıdaki kod eklenir.
Interlocked.Increment(refCounter.Count);

 

UpdateCount metodunu senkronize etmek için lock(this){//—} arasına kodları yazılır. Senkronizasyon lock kullandığımızda UpdateCount metodunun koduna aynı aynı anda sadece bir threadin erişmesini faranti ederiz.

Monitor.Enter(this); static metodu belirtilen nesneyi kilitler.
Monitor.Exit(this); Kilidi kaldırır. Bunları kullanırsak lock metoduna gerek kalmaz.

Deadlock : Eğer iki kod parçası aynı nesneye aynı anda erişmeye çalışırsa deadlock oluşur.Deadlocklardan kurtulmak için Monitor.TryEnter metodu kullanılabilir ve lock ların sayısı azaltılabilir.

Diğer senkronizasyon metodları : ReaderWriterLock ,

Windows Kernel Senkronizasyon Nesneleri : Mutex(lock gibidir) ,Semaphore, AutoResetEvent, ManualResetEvent : Bu nesneler senkronizasyonu sağlamak için kullanılabilir ancak örneğin Monitor yerine Mutex kullanmak 33 kat daha yavaştır.

Asenkron Programlama Modeli (APM) : Bu model basitçe farklı kod parçalarını farklı threadlerde çalıştırma olarak tanımlanabilir.Bu sistem kaynaklarını daha efektif kullanabilmemizi sağlar.Nesnelerin BeginXXX ve EndXXX patternine uygun metodları varsa asenkron kod çalıştırılabilir demektir.

byte[] buffer = newbyte[100];

string filename = string.Concat(Environment.SystemDirectory, “\IE7Eula.rtf”);

FileStream fs = newFileStream(filename, FileMode.Open, FileAccess.Read,

    FileShare.Read,1024, FileOptions.Asynchronous);

 

IAsyncResult result = fs.BeginRead(buffer, 0, buffer.Length, null, null);

int numBytes = fs.EndRead(result);

fs.Close();

Console.WriteLine(“Read {0} bytes”,numBytes);

   Console.WriteLine(BitConverter.ToString(buffer));

 

Bundan önceki örneklerimizde hep kendi Threadlerimizi yaratıp bu threadler üzerinden işlem yaptırdık fakat kendi threadini yaratmak tavsiye edilen bir yöntem değil.Bunun yerine .NET’in kendi ThreadPool’unu kullanmak daha sağlıklı olacaktır.

//Bu kod yeni bir thread oluşturmaz ancak havuzda var olan bir threadi tekrardan

//kullandığı için daha hızlıdır ve daha az memory harcar.

WaitCallback workItem = newWaitCallback(WorkWithParameterMetod);

if (!ThreadPool.QueueUserWorkItem(workItem, “ThreadPooled”))

{

    Console.WriteLine(“Could not queue item”);

}

int threads,completionPorts;

ThreadPool.GetMaxThreads(out threads, out completionPorts);

ThreadPool.SetMaxThreads(threads + 10, completionPorts + 100);

 

ASP.NET uygulamalarında Windows uygulamalarından farklı olarak SynchronizationContext sınıfı ile işlemler yapılır.

SynchronizationContext ctx = newSynchronizationContext();

ctx.Send(RunMe,“Hi”);

ctx.Post(RunMe,“Hi”);

Threading hakkında anlatacaklarım bu kadar umarım yararlı olmuştur.

Mayıs 25, 2010 Posted by | C# | , , , , | Yorum bırakın

C# Grafikler

Grafikler uygulamaların kullanıcı arayüzlerini zenginleştirmek için kullanılırlar.Örneğin raporlar,çizelgeler,resimler bu amaca hizmet etmek için kullanılabilir.NET Framework kendi içerisinde System.Drawing namespace’i altında çizgi,şekil,patternler ve text çizmek için sınıflar barındırır.Bu yazıda da .NET ile nasıl grafik ve resim çizilir bunları işliyor olacağız.
Grafik çizebilmek için öncelikle bir windows forms uygulamasına ihtiyacımız olacak.

Pen sınıfı abstract Brush sınıfından türemiş doğru ve eğriler çizmeye yarayan bir sınıftır.

Bir nesnenin form üzerindeki konumunu da Point sınıfı yardımı ile belirleyebiliriz.
button1.Location = new Point(10,10);

Veya
button1.Left = 10;

button1.Top = 10;
Bir nesnenin boyutunu ise Size sınıfı yardımı ile belirleyebiliriz.
button1.Size = new Size(30,30);

Bir nesnenin rengini Colır structure’i ile belirleyebiliriz.
button1.Color = Color.Red;
Eğer custom bir renk istiyorsak Color.FromArgb(100,5,88); şeklinde tanımlayabiliriz.

Aşağıdaki kod parçası panel1’e kırmızı ve kalınlığı 7 pixel olan bir kalem ile (1,1) noktasından (100,100) noktasına bir çizgi çizmektedir.
Graphics g = this.panel1.CreateGraphics();

Pen p = newPen(Color.Red,7);

g.DrawLine(p,1,1,100,100);

Panele pasta dilimi çizmek.
Graphics g = this.panel2.CreateGraphics();

Pen p = newPen(Color.Red, 7);

g.DrawPie(p, 1, 1, 100, 100,-30,60);

Ekrana poligon çizdirmek.
Graphics g = this.panel3.CreateGraphics();

Pen p = newPen(Color.MediumPurple, 2);

Point[] points = newPoint[] {

newPoint(10,10),newPoint(10,100),

newPoint(50,65),newPoint(100,100),newPoint(85,40)};

g.DrawPolygon(p, points);

 

Doğruyu farklı biçimlerde formatlamak
Graphics g = this.panel4.CreateGraphics();

Pen p = newPen(Color.Purple, 7);

 

p.DashStyle = DashStyle.Dot;

g.DrawLine(p, 50, 25, 400, 25);

 

p.DashStyle = DashStyle.Dash;

g.DrawLine(p, 50, 50, 400, 50);

 

p.StartCap = LineCap.ArrowAnchor;

p.EndCap = LineCap.Round;

g.DrawLine(p,50,75,200,75);

 

Bir poligon çizdirip içerisini ve kenarlarını farklı renklerde boyamak.

Graphics g = this.panel5.CreateGraphics();

Brush b = newSolidBrush(Color.Blue);
//Brush b = new LinearGradientBrush(new Point(1, 1), new Point(100, 100), Color.Maroon, Color.Blue); // Gradient olarak içerisini boyama yapar.

g.FillPolygon(b, points);

Pen p = newPen(Color.Maroon, 7);

g.DrawPolygon(p, points);

 

Formun arka planına resim çizdirmek
privatevoid frm_6_Graphics_Paint(object sender, PaintEventArgs e)

{

    Bitmap bm = newBitmap(@”C:Mavi Tepeler.jpg”);

    Graphics g = this.CreateGraphics();

    g.DrawImage(bm, 1, 1, this.Width, this.Height);

}

 

Ekrana ikon çizdirmek:

Graphics g1 = this.CreateGraphics();

g1.DrawIcon(SystemIcons.Information, 400, 400);

Ekrana yazı yazmak:
Font f = newFont(“Arial”, 40, FontStyle.Bold);

g.DrawString(“Koray Kırdinli”,f,Brushes.Purple,400,430);

Rectangle r = newRectangle(newPoint(500, 500), newSize(80, 80));

StringFormat f1 = newStringFormat(StringFormatFlags.NoClip);

StringFormat f2 = newStringFormat(f1);

f1.LineAlignment = StringAlignment.Near;

f1.Alignment = StringAlignment.Center;

 

g.DrawRectangle(Pens.Black,r);

g.DrawString(“A B C”,this.Font,Brushes.Red,(Rectangle)r,f1);

Mayıs 18, 2010 Posted by | C# | , , , | Yorum bırakın

C# ile Serilizasyon ve Deserilazasyon

Bir çok uygulama bir nesne içerisinde veriyi saklamaya veya transfer etmeye ihtiyaç duyar. Bunu .NET içerisinde yapmanın en kolay yolu serilizasyondur. 3 tip serileştirme tekniği vardır. Bunlar Binary, SOAP ve XML Serilization.
Bir uygulamada veriyi memory’de serileştirip saklamak , network üzerinden transfer etmek ve tekrardan nesneyi oluşturmak serilizasyon ve deserilizasyon ile mümkündür.
Serilizasyon bir nesneyi alıp bir dizi lineer byte dizisine çevirme işlemidir diyebiliriz.
Serilizasyon sınıfları System.Runtime.Serialization namespace’i altındadır.

Serilizasyon nerede işimize yarar:
Eğer bir nesneyi bir dosyaya serileştirme yapmadan yazıp daha sonra okumak istersek bu sefer nesnenin property’lerini manuel olarak set etmemiz gerekecek fakat serilizasyon işleminde nesneyi olduğu gibi geri alabilmek mümkün.
Diğer bir örnek: Bir nesneyi farklı bir bilgisayarda çalışan bir programa network üzerinden bu nesneyi gönderebilir , remoote uygulamada bu nesneyi deserilize edip işlemlerini yapabilir.
Windowsta bir nesneyi clipboard’a kopyaladığımızda,web servislerinde,remoting yaparken serilizasyon  yapmaktadır.

Basit olarak bir binary serileştirme işleminin adımlarını yazacak olursak.
1- Stream nesnesi oluşturulur ( File veya MemoryStream)
2- BinaryFormatter nesnesi oluşturulur
3- Formatter’ın serialize metodu çağrılır ve stream kapatılır.

string data = “Koray Kırdinli”;

FileStream fs = newFileStream(“SerializesString.Data”, FileMode.OpenOrCreate);

BinaryFormatter bf = newBinaryFormatter();

bf.Serialize(fs, data);
fs.Close();

Fakat yukarıdaki işlemde serilizasyon yapmak çok efektif değil düz bir şekilde dosyaya da yazabilirdik. Serilizasyon daha kompleks işlemlerde asıl faydasını göstermekte yani nesneleri. Örneğin bir teks değilde DateTime’ı serilize etmek örnek olarak verilebilir.

Desirilazasyon işlemi ise serilizasyonun tam tersidir. Aşağıdaki kod yardımı ile serilize ettiğimiz bir nesneyi geri almamız mümkün.

FileStream fs = newFileStream(“SerializesString.Data”, FileMode.Open);

BinaryFormatter bf = newBinaryFormatter();

string data = (string)bf.Deserialize(fs);

fs.Close();
Kendi yazdığımız bir sınıfı da Serilizable niteliği sayesinde serilize edilebilir hale getirebiliriz. Ayrıca serilizasyon işlemi System.Security.Permissions namespace’i altındaki SecurityPermission niteliğine ihtiyaç duyar. Default olarak bu policy’ye internetten indirilen veya intranet bir kod parçasında izin verilmez fakat  lokal makinada izin verilir. Bunun sebebi ise gizli veriyi koruma altına almaktır.

[Serializable]

publicclassShoppingCartItem : IDeserializationCallback

{

    publicint ProductId;

    publicdecimal Price;

    publicint Quantity;

    [NonSerialized] publicdecimal Total; // Bu değer dinamik hesaplandığı için

    //ve verinin boytunu küçültmek için serilize etmiyoruz.

 

[OptionalField] publicbool Taxable;

//Eğer bir field’a OptionalField niteliğini eklersek bu field daha önce serilize

//edilmiş veride olmasa bile uygulama hata fırlatmaz. Versiyon uyumluluğu için kullanılabilir.

 

#region IDeserializationCallback Members

//Bu sınıfın nesnesi deserilize olurken IDeserializationCallback interface’ini

//implement edip OnDeserialization eventi içerisinde hesaplatma işlemini yapıyoruz.

        publicvoid OnDeserialization(object sender)

        {

            Total = Price * Quantity;

        }

#endregion

    }
.NET Framework serilize edilmiş veriyi formatlamak için System.Runtime.Serialization namespace’i altında 2 formatlayıcı barındırıyor. İkisi de IRemotingFormatter interface’ini implemente eder.
BinaryFormatter : System.Runtime.Serialization.Formatters.Binary namespace’i altındadır. Eğer serilize eden ve deserilize eden uygulama .NET ile yazılmışsa kullanılmalıdır.
SoapFormatter : System.Runtime.Serialization.Formatters.Soap namespace’i altındadır.Eğer deserilize edecek uygulama .NET ile yazılmamışsa kullanmak mantıklıdır. Ayrıca Firewall’lardan daha rahat geçer. Yani network uygulamalarında daha başarılıdır.Kullanmak için System.Runtime.Serialization.Formatters.Soap.dll ‘i uygulamaya referans vermek gereklidir. Binary Formatter ile serileştirilmiş veriyi okuması daha zor iken Soap ile serileştirilmiş veri xml tabanlı daha düzgün bir şekilde okunabilir.

ShoppingCartItem entity = newShoppingCartItem(1, 100m, 10, 1000);

FileStream fs = newFileStream(“SerializeSoap.Data”, FileMode.OpenOrCreate);

SoapFormatter bf = newSoapFormatter();

bf.Serialize(fs,entity);

fs.Close();

 

 

1

100

10

false

 

 

 
ShoppingCartItem entity = newShoppingCartItem();

FileStream fs = newFileStream(“SerializeSoap.Data”, FileMode.Open);

SoapFormatter bf = newSoapFormatter();

entity = (ShoppingCartItem)bf.Deserialize(fs);

fs.Close();

MessageBox.Show(

    String.Format(“Pid:{0},Price{1},Quantity={2},TOTAL={3}”,

    entity.ProductId,entity.Price,entity.Quantity,entity.Total));
XML serileştirme veriyi farklı sistemlerin veri alışverişini sağlayabilmek amacıyla oluşturulmuş XML yapısında saklamaktadır..NET içerisinde XML dökümanına yazma ve okuma için bir çok sınıf mevcuttur. System.Xml.Serialization namespace’i altında serileştirme sınıflarını bulabilirsiniz.
Peki ne zaman Xml serileştirme kullanmalıyız :  Eğer deserilize edecek uygulama .NET değil ve nesne olduğu gibi serileştirilecek ise XML serileştirme kullanılabilir. Bu yöntem text tabanlı olduğu için bütün işletim sistemlerinde ve uygulama ortamlarında kolayca okunabilir. Ayrıca bir notepad gibi basit bir araçla bile kolayca okunabilir. Özellikle uygulamaları customize etmekte oldukça kullanışlıdırlar.

FileStream fs = newFileStream(“SerializeDate.xml”, FileMode.OpenOrCreate);

XmlSerializer xs = newXmlSerializer(typeof(DateTime));

xs.Serialize(fs, DateTime.Now);

fs.Close();

MessageBox.Show(DateTime.Now.ToLongTimeString());

FileStream fs = newFileStream(“SerializeDate.xml”, FileMode.Open);

XmlSerializer xs = newXmlSerializer(typeof(DateTime));

DateTime date = (DateTime)xs.Deserialize(fs);

fs.Close();

MessageBox.Show(date.ToLongTimeString());   

 

Bir sınıfı aşağıdaki şekilde Xml serilizasyona uygun hale getirebiliriz.

[XmlRoot(“Cart”)]

publicclassCartItem

{

    [XmlAttribute] publicInt32 productId;

    publicdecimal price;

    publicInt32 quantity;

    [XmlIgnore] publicdecimal total;

}
Eğer iki farklı uygulama xml dosyaları paylaşacaklar ise developer’lar xml standartlarını ortak olarak belirleyebilmek için xml schema’lardan yararlanırlar.Xml schema xml dökümanının yapısını belirler.Xml schemaları oluşturmak için xsd.exe gibi bir araçtan faydalanılabilir.Veya standart olarak .NET içerisindeki XmlReader ve XmlWriter sınıflarından yararlanılabilir.

Bir dataseti ister yukarda anlattığımız yöntem ile ya da myDataSet.WriteXml(“DataSet.xml”); metodu ile direk olarak serilize edebiliriz.

Custom Serilization : Bir sınıfı ISerilizable sınıfının GetObjectData metodunu override ederek default serilizasyonu kullanmadan custom bir serilizasyon yapabiliriz. Bu bir nesnenin geçersiz bir elemanı olduğunda işimize yarayabilir.
GetObjectData metonunda parametre olan SerilizationInfo nesnesi içerisine elemanları doldurmak gereklidir.Bu elemana name/value çifti olarak elemanlar yerleştirilir.

 

 

 

 
[SecurityPermissionAttribute(SecurityAction.Demand,SerializationFormatter=true)]

publicvoid GetObjectData(SerializationInfo info, StreamingContext context)

{

    info.AddValue(“Product Id “, productId);

    info.AddValue(“Price”,price);

    info.AddValue(“Quantity”, quantity);

}

 

Serilizasyon işlemlerinde istediğimiz aşamada veriye müdahale etme şansımız bulunmaktadır. Bunu xml nitelikleri ile yapabiliyoruz.
[OnSerializing] : Sınıf içerisine bir metoda bu tagı eklersek o metod nesneyi serilize ederken çalışır.

[OnSerialized] : Serilizasyon işlemi bittikten sonra çalışır.

[OnDesilizating] : Desilize işlemi nesne deserilize işlemi yapılırken çalışır.

IDesirilizationCallback,OnDesilization()
[OnDesirialized] : Deserilize işlemi bitince çalışır.

[Serializable]

publicclassCustomer

{

    publicInt32 productId;

    publicdecimal price;

    publicInt32 quantity;

    publicdecimal total;
//Bu metodalar parametre olarak StreamingContext almak ve void return etmek //zorundadırlar.

    [OnSerializing]

    void CalculateTotal(StreamingContext sc)

    {

        total = price * quantity;

    }

 

    [OnDeserialized]

    void CheckTotal(StreamingContext sc)

    {

        if (total == 0) CalculateTotal(sc);

    }

}

Mayıs 17, 2010 Posted by | C# | , , , | Yorum bırakın

WPF Eğitimi Sonrası

Geçen haftasonu Aykut Taşdelen hocadan bir WPF eğitimi aldık kurum olarak. Eğitim yerimiz The Marmara oteli idi.İlk başta otelin pek bir özelliğinin olmadığını düşündük arkadaşlarla taa ki otelin çatısına çıkana kadar. Mükemmel bir istanbul manzarası karşıladı bizi çatıda. Sizlerde bu fotoları paylaşmak istedim. İstanbulu çok farklı açılardan izleme şansım olduğu için kendimi şanslı hissediyorum

 

Mayıs 14, 2010 Posted by | Etkinlikler | , , | Yorum bırakın

C# ile Oracle’a Bağlanma Sorunum

Kurum içerisinden oracle’a bağlanma ihtiyacım olmuştu.Evdeki bilgisayarımda hiç bir ekstra ayar yapmadan kolayca başlanabilmiştim ancak şirkette baya uğraştırdı beni doğrusu ama sonunda oldu. Oracle’a bağlanabilmek için hemen System.OracleClient namespace’ini kullanayım dedim ancak versiyon farkından dolayı bana
System.Data.OracleClient requires Oracle client software version 8.1.7 or greater.
hatasını verdi. Hemen bir araştırma yapıp OracleClient 10.2 yi buldum
OracleClient’ı kurunca NetManager ve Net Configuration Asistant yardımıyla D:oracleproduct10.2.0client_1NETWORKADMIN dizini altına tnsnames.ora ve sqlnet.ora ve listener.ora dosyalarını doğru şekilde oluşturdum.
Toad ile bu tnsname ‘i kullanarak bağlanabiliyordum ancak C#’tan ve sqlplus’ı kullanarak hala erişememiştim. ora-12154 tns could not resolve the connect identifier specified hatası alıyordum.
Bunu aşmak içinde Control Panelin altına ODBC Data Source Administrator’a providerımı Add diyerek ekledim.

Daha sonra da connection stringimi tnsname ile aynı yaptım aşağıdaki gibi ve mutlu son

Mayıs 14, 2010 Posted by | C#, Oracle | , , | Yorum bırakın

C# ile Active Directory İşlemlerine Giriş

Merhaba arkadaşlar
Bu makalemizde Active Directory nedir,ne değildir,ne zaman kullanabiliriz,nasıl çalışır bu gibi konulara değinmeye çalışacağım. Öncelikle nerden ihtiyacım oldu ve neden makale yazma ihtiyacı duyduğumdan yola çıkarak Active Directory’i ne zaman kullanabilirsiniz sorusuna cevap vermeyi düşünüyorum.
İş yerinde basit bir database sorgusu çekip bir kaç bilginin yanında ilgili kullanıcının full name’ini ve departmanını göstermem gerekti. Fakat kullanıcının full name’i ve departmanı benim kullandığım database’de mevcut değildi. Ben de alternatif bir yol olarak bir kaç kişinin tavsiyesi ile bu bilgileri Active Directory’den çekmeye karar verdim.

Bu işlemin nasıl yapıldığına geçmeden önce kısada Active Directory yapısından bahsetmekte yarar var diye düşünüyorum.Aslında Active Directory tam olarak hiyerarşik yapıda olmasa da bazı ilkelerin yönetildiği ve belirlendiği  bir veritabanıdır diyebiliriz kabaca. LDAP(Lightweight Directory Access Protocol : TCP/IP üzerinde çalışan dizin servislerini sorgulamak ve düzeltmek için kullanılan bir ağ iletişim kuralıdır) denilen bir sorgulama mantığı sayesinde bu bilgiler üzerinde sorgulamalar yapabilmek mümkün.Açık kaynak kodlu LDAP’ı http://www.openldap.org adresinden indirip kurabilirsiniz.LDAP sadece Windows serverları için değil UNIX ve LINUX serverları için de kullanılan bir mantıkmış.

LDAP’ın normal veritabanından en önemli farkı dizin yapısını temsil ettiği için mantıksal olarak bir nesnenin altında bulunan bir başka nesne fiziksel olarakta altındadır. LDAP ile bir kayıt eklemek ve silmek veritabanına göre yavaş olsa da ,arama yapmak daha hızlıdır.Bu yüzden Adres Defteri gibi bir kez kaydedilip defalarca aynı nesnelerin çağrıldığı yapılar için uygundur.

O=Organizasyon adı
—-OU=members
———CN=user1
———CN=user2
—-OU=printers
———CN=printer1
———CN=printer2

LDAP için bazı kısaltmalar şu şekildedir : O=Organizasyon,OU=Organization Unit,CN=Common Name,ad soyad,SN=Surname,C=Country

Windows 2000 server ile gelen LDAP sorgulama mantığı  ile çalışan nesnelerin oluşturulduğu, yönetildiği ve ilkelerin belirlendiği veritabanıdır.  Kurulum için 2000 server yada 2003 server versiyonlarından birinin yüklü olması gerekir. LDAP sorguları ile çalıştığı için UNIX, LINUX gibi işletim sistemlerine migrate ( dönüştürme ) yapılabilir.
Active Directory ile ilgili bir kod yazabilmek için öncelikle network security, business rules, ve technological constraints terimlerine aşina olmak gereklidir.Active Directory içerisinde gruplar,isim,soyisim,email,organizasyon gibi nesneler yer alır.

İşin C# tarafına bakacak olursak System.DirectoryServices namespace’i altında en sık kullanacağımız iki sınıf DirectoryEntry ve DirectorySearcher sınıflarıdır.DirectoryEntry AD içerindeki tek bir nesneyi ifade eder.DirectorySearcher ise merkez sistemdeki nesneler arasında arama yapmamızı sağlar.
Aşağıdaki örnek kendi kurumunuzun LDAP bilgilerine göre düzenlenip istenilen sonuçlar elde edilebilir.

public string GetADUsers(){
StringBuilder sb = new StringBuilder();
//Sunucuya bağlanmak için LDAP filtresi verilebilir.Verilmez ise bütün nesneler gelir.
DirectoryEntry entry = new DirectoryEntry(“LDAP://”);
DirectorySearcher search = new DirectorySearcher(entry);
search.Filter = “(objectCategory=user)”;// sadece kullanıcılar
string[] properties = new string[] { “fullname”, “cn”, “department”, “samaccountname” }; //istenilen alanlar
search.PropertiesToLoad.AddRange(properties);
foreach (SearchResult AdObj in search.FindAll()){
//string cn = AdObj.GetDirectoryEntry().Properties[“cn”].Value.ToString();
foreach (object p in AdObj.Properties.PropertyNames)
{
sb.AppendLine(p.ToString() + “:::” + AdObj.Properties[p.ToString()][0].ToString());
}
System.IO.File.WriteAllText(@”c:kh.txt”, sb.ToString());
}
return sb.ToString();
}

Umarım az da olsa yararlı olmuştur.
Herkese iyi çalışmalar.

 

Mayıs 2, 2010 Posted by | C# | , , , | Yorum bırakın

MCTS – 4.Collections and Generics

4. Collections and Generics

Collection’lar veriyi saklamak,gruplamak ve içerisinde gezinmek için kullanılırlar.Array’ler de bu işe yarar fakat collection’lar array’lerin geliştirilmiş versiyonudur.

System.Collections namespace’i : Arraylist, Collection interfaces, iterators, Hastable, CollectionBase sınıfı,ReadOnlyCollectionBase sınıfı, DictionaryBase sınıfı, DictionaryEntry sınıfı, Comparer sınıfı, Queue sınıfı, SortedList, BitArray, Stack,

System.Collections.Specialized namespace’i : Specialized String sınıfları, Specialized Dictionary, NameValueCollection sınıfı, CollectionsUtil , BitVector32 structure içerir

System.Collections.Generic namespace’i : Collection.Generic interfaces, Generic Dictionary, Generic Comparer, GenericEquality Comparer, Generic KeyValuePair Structure, Generic List,Generic List.Enumerator structure, Generic Sorted List, Generic Queue, Generic SortedDictionary, Generic LinkedList, Generic Stack içerir.

 

Kendi Sort sınıfınızı yazmak :

Normalde arrayler ve listelerin standart Compare metodu vardır bu metod iki değeri karşılaştırır ve birinci değer büyük ise -1 , ikinci değer büyükse 1 , eşitse 0 döndürür. Biz IComparer interface’ini implemente etmiş kendi sınıfımızı yazıp daha sonra Sort metoduna bu Comparer’ı verirsek artık sort işlemi bizim belirlediğimiz kriterlere göre karşılaştırma yapar. Aşağıdaki örnek Comparer tersten sıralamayı anlatmaya çalışmaktadır.

publicclassDescendingStringComparer : IComparer

{

        CaseInsensitiveComparer _comparer = newCaseInsensitiveComparer();

 

#region IComparer Members

        publicint Compare(object x, object y)

        {

            //Bu kod sayesinde (x,y değil y,x) testen sıralama yapılır.

            return _comparer.Compare(y, x);

        }

#endregion

}

list.Sort(newDescendingStringComparer());
şeklinde bir listeyi sort edersek bu sefer küçükten büyüğe değil büyükten küçüğe sıralama yapacaktır.

 

Sequential Lists:
Queue : Kuyruk FIFO ilk giren ilk çıkar şeklinde çalışır. Bir kuyruğa yeni bir eleman eklemek için
Queue q = newQueue();

q.Enqueue(“a”);

q.Enqueue(“b”); geriye bir değer döndürmez.

 

Kuyruktan bir eleman çıkarmak için ise q.Dequeue(); kullanılır ve ilk eleman listeden çıkarılır yani a çıkarılır ve geriye object olarak çıkardığı eleman döner. Eğer kuyruktan eleman çıkarmadan sıradaki elemanla ilgili işlem yapılmak isterse Peek() metodu kullanılabilir.

if (q.Peek() isString)

   q.Dequeue();

 

Stack: Kuyruğun tam tersi mantıkta çalışır LIFO ilk giren son çıkar mantığıyla çalışır.
Stack’a eleman eklemek için Push çıkarmak için Pop metodu kullanılır.

Stack s = newStack ();

s.Push(“a”);

s.Push(“b”);
object o = s.Pop();
//Pop metodundan çıkarılan eleman döner.

Dictionaries:

Hastable : Key-Value şeklinde veri saklamak için kullanılır. Bir dataya bir anahtar yardımıyla erişmek için Hashtable çok kullanışlıdır ancak eleman sayısı az olan listelerde Hastable yerine ListDictionary kullanmak performans açısından daha etkilidir.Hashtable’a veri eklemek ve listelemek aşağıdaki gibidir.
Hashtable h = newHashtable();

h[“adi”] = “koray”;

h[“mail”] = “koraykirdinli@yahoo.com”;

foreach (DictionaryEntry item in h)

{

    listBox4.Items.Add(item.Key +” : “+ item.Value);

}

 

DictionaryEntry key/value çiftlerini saklamak için kullanılan bir konteyner nesnedir. Bütün Dictionary sınıfları IDictionary interface’ini implement eder. IDictionary interface’inin önemli property ve metodları şunlardır.
IsFixedSize,IsReadOnly,Item,Keys,Values – Add,Clear,Contains,GetEnumarator,Remove.

IDictionary interface’inde IList interface’inden farkı IList nesnelere indexi ile IDictionary nesneleri anahtar değeri ile erişir.

Hashtable listelerde bir key veya Value değerinin var olup olmadığını anlayabilmek için iki metod vardır:ContainsKey,ContainsValue. Hashtable listede aynı keye sahip birden fazla key olamaz.

Eğer Hashtable’a key olarak bir sınıf nesnesi vererek eklersek bu sefer Name’leri aynı olsa bile farklı olarak algılar.

Person p1 = newPerson(“Koray”);

Person p2 = newPerson(“Koray”);

Hashtable h2 = newHashtable();

h2[p1] = “a”;

h2[p2] = “a”;

//Bu sefer Person sınıfının Equals ve GetHashCode metodlarını override ettiğimiz için

//bütün özellikleri aynı olsa da farklı iki eleman olarak alır.
publicclassPerson

{

    publicstring Name;

    public Person(string name)

    {

        Name = name;

    }

    publicoverridebool Equals(object obj)

    {

        Person other = obj asPerson;

        if (other == null) returnfalse;

        return other.Name == Name;

    }

    publicoverrideint GetHashCode()

    {

        return Name.GetHashCode();

    }

}

//———————————————————————————-

 

publicclassInsensitiveComparer : IEqualityComparer

{

    //Bu comparer karşılaştırmayı case-insensitive olarak yapmayı sağlar.

    CaseInsensitiveComparer _comparer = newCaseInsensitiveComparer();

 

    publicint GetHashCode(object obj)

    {

        return obj.ToString().ToLowerInvariant().GetHashCode();

    }

 

    publicnewbool Equals(object x, object y)

    {

        if (_comparer.Compare(x, y) == 0)

        {

            returntrue;

        }

        elsereturnfalse;

    }

}

Hashtable h3 = newHashtable(newInsensitiveComparer());

h3[“aa”] = “a”;

h3[“Aa”] = “a”;

h3[“AA”] = “a”;

Console.WriteLine(h3.Count);// insensitive comparer kullandığımız için 3 değil 1’dir.

 

//———————————————————————————-

 

SortedList:

//SortedListlerde Hashtable’a ek olarak bir elemana hem key ile hem de index ile //erişebiliriz. Elemanı eklediğimiz anda listede uygun yere ekleme yapar.

SortedList list = newSortedList();

list[“First”] = 1;

list[“Second”] = 2;

list[“first”] = “1”;

//Yukardaki listede indexler bu şekilde oluşur. 0:first,1:First,2:Second

 

list.GetByIndex(2);

foreach (DictionaryEntry item in list)

{

    listBox5.Items.Add(item.Key+” : “ +item.Value);

}

 

Özelleştirilmiş Dictionary’ler:

 

Eleman sayısı 10 dan az ise Hastable yerine ListDictionary kullanmak performans açısından daha iyidir.ListDictionary Hastable ile aynı interface’leri implement eder , kullanımı da aynıdır.

 

HybridDictionary: Eğer bir listenin eleman sayısının az veya çok olduğunu önceden kestiremiyorsak HybridDictionary kullanılmalıdır. Interface’leri ve kullanımı yine aynıdır.

 

OrderedDictionary: Keyleri sıralı bir listeye ihtiyacınız olduğunda Hastable işe yaramaz ayrıca bir elemana indexi ile erişmekte mümkün olmaz. SortedList ise keyler beklediğiniz gibi sıralanmıyorsa OrderedDictionary kullanılabilir. Ekstra birkaç özelliği daha vardır.

Özelleştirilmiş tipi olan Koleksiyonlar.

BitArray : true , false tutmak için kullanılır ve elemanları Xor , And gibi bitsel işlemler yapılabilir.
BitVector32 : bitleri 32 bit integer değer olarak saklamaya yarar.
StringCollection : ArrayList gibidir ancak sadece string içerir.

 

 

Bir Hashtable veya SortedList’i case insensitive yapmak için aşağıdaki şekilde yaratabiliriz.
Hashtable ht= CollectionsUtil.CreateCaseInsensitiveHashtable();

SortedList sl = CollectionsUtil.CreateCaseInsensitiveSortedList();

 

Normal şartlarda karşılaştırma işlemi o anki thread’in bölgesel ayarına göre yapılır ancak bunu değiştirmek aşağıdaki kod ile mümkün.

Hashtable ht2 = newHashtable(StringComparer.InvariantCulture);

 

NameValueCollection : key/value alır ancak bir keye ait birden fazla value olabilir.

NameValueCollection list = newNameValueCollection();

list.Add(“key1”, “value1”);

list.Add(“key1”,“value2”);

list.Add(“key2”, “value3”);

foreach (string s in list.GetValues(“key1”))

{

    listBox6.Items.Add(s);

}
//———————————————————————————-

 

GENERIC COLLECTIONS

Generic koleksiyonların daha önce bahsettiğimiz Arralist,HashTable gibi koleksiyonlardan en önemli farkı type-safe yani belli bir tipte olması , boxing unboxing den kurtulmamızı ve dolayısıyla performansımızı artırmamızı sağlar. Böylece run time da istenmeyen hataları da azaltmış oluruz.

publicclassMyList : ICollection, IEnumerable

{

  //Bu sınıf sadece T tipinde değere alan bir koleksiyondur. Kendimiz tip güvenli yapmış olduk. T bu sınıf tanımlanırken integer,string vs olarak tanımlanabilir.

        ArrayList array = newArrayList();

 

        publicvoid Add(T val)

        {

            array.Add(val);

        }

        public T this[int index]

        {

            get { return (T)array[index]; }

        }

#region ICollection Members

#endregion

 

#region IEnumerable Members

#endregion

 }

 

//Bu tanımlama sayesinde bu liste sadece integer değer alabilir hale geldi.Arraylistin sadece integer alan versiyonu aşağıdaki gibidir.

List<int> list = newList<int>();

list.Add(1);

//list.Add(“2”); ERROR

 

 

 

Generic Delegates:

publicdelegateintComparison(T x, T y);

Bunun avantajı örneğin bir listeyi testen yazdıran bir Comparison nesnesi yapmak istiyorsunuz ancak her bir tip için de bunu tek tek yapmak uzun sürecektir. Bunun yerine Comparison delegesi generic olduğundan tek bir metod ile işlem yapılabilir.

 

Generic queue ve stack da aşağıdaki gibi oluşturulur kullanımı generic olmayan versiyonu ile aynıdır.

Queue<string> queue = newQueue<string>();

Stack<int> stack = newStack<int>();

 

 

Generic Dictionary : Hashtable,ListDictionary ve HybridDictionary koleksiyonlarının generic halidir.
Dictionary<int, string> list = newDictionary<int, string>();

list.Add(1, “koray”);

list.Add(2,“kirdinli”);

list[3] = “aaaaaa”;

 

//Diğer bazı generic koleksiyonların tanımlanması aşağıdaki gibidir.
SortedList<string, bool> sl = newSortedList<string, bool>();

Mayıs 1, 2010 Posted by | C# | , , , , | 1 Yorum