Polymorphism ve Dependency Injection

Geçen hafta yazılımcı arkadaşlarla iş görüşmeleri yaparken aklımıza geldi. Neredeyse her iş görüşmesinde soruyoruz; Nedir bu Polymorphism veya Dependency Injection. Görüşmeye gelenlerin %20’sinden cevap alıyoruz. Fakat biz de bu yabancı terimleri Türkçe ifade etmeye çalıştığımızda zorlandık, dilimiz dönmedi. Ya sürekli yabancı kaynak okumaktan ya da gerçekten Türkçe açıklamasının zor olduğundan. Aşağıda kısaca bu kavramları olabildiğince Türkçe anlatmaya çalışayım.

Polymorphism (Çok Biçimlilik)

Nesne yönelimli programlamada (Object Oriented Programming) birçok aynı özelliğe sahip nesnenin ortak özelliklerini bir arayüz veya soyut sınıf (Interface veya Abstract Class) ile belirtip, nesneleri bu arayüzden veya soyut sınıftan türetebiliyoruz. Bu özelliğe kalıtım (inheritence) diyoruz.

Aynı özelliğe sahip bu türetilmiş nesneleri, her nesnenin kendi tipi değil de türettiğimiz arayüz veya soyut sınıf tipi ile yani ortak özellikleri ile kullanırsak, bu özelliğe ait hangi nesne gelirse gelsin aynı kodun içinde kullanabiliyor, ata sınıfını kullanarakk aynı tipmiş gibi davranabiliyoruz. İşte buna Polymorphism deniyor.

En çok gerçek hayat örneği sanırım banka komponentleri için verilebilir. Diyelim ki Garanti Bankası ve Yapı Kredi Bankası POS işlemleri için sınıflarınız var. Her iki sınıfta da Sale (satış) ve InstallmentSale (Taksitli Satış) metodlarınız var. Eğer bunları bir Interface’den türetirseniz aşağıdaki gibi bir yapı elde edersiniz;

public interface IBank
{
public int Sale();
public int InstallmentSale();
}

public class GarantiBankasiPos : IBank
{
public int Sale()
{
// sale kodu buraya
}
public int InstallmentSale()
{
// InstallmentSale kodu buraya
}
}

Ortalığı karıştırmamak için metod parametrelerini ve içindeki kodu yazmadım. Yukarıdaki yapıdaki her banka pos sınıfı için Sale() metodunu kodladığım durumda aşağıdaki gibi bir kodla bankadan bağımsız satış yapabilir hale gelirim;


public int DoSale(IBank bank, parametreler ....)
{
// parametre kontrolleri ve diğer iş kuralları uygulama kodu
return bank.Sale(parametreler ...);
}

İşte burada Polymorphism uygulamış olduk. Banka tipinden bağımsız olarak kontrollerimizi gerçekleştirip satışı tek metod üzerinden yapabiliyoruz. Bu bizi kod tekrarından korudu, kodumuzu basitleştirip bakım ve yeni pos sınıfları eklememizi kolaylaştırdı. Artık aynı şekilde ekleyeceğimiz her pos sınıfını IBank’tan türeterek aynı kodun içine referans olarak verdiğimizde o banka ile işlem yapabileceğiz.

Dependency Injection (Bağımlılık Enjeksiyonu)

Bağımlılık Enjeksiyonu, Dependency Injection’un birebir çevirisi olduğu için kullandım. Aslında şimdiye kadar geçen terimlerin Türkçe’sini günlük hayatta hiç kullanmıyoruz. Herkes Dependency Injection veya DI olarak, Polymorphism, Interface, Abstract Class olarak bu kavramları kullanıyor.

Peki Dependency Injection nedir? Dependency Injection, bir sınıfın içindeki farklı görevleri, o sınıfa dışarıdan parametrik olarak verebilmektir. Yani iş kuralları olan sınıfımın içinde veritabanı işlerini yapmayıp, bu işlevi veritabanı yardımcı sınıfı olarak ayırıp, referansını iş kuralları sınıfıma parametrik olarak geçebilirim. Örneğin;

public class PaymentManager
{
private ILogger _logger;

public PaymentManager(ILogger logger)
{
_logger = logger;
}

public void DoPayment()
{
// DoPayment iş kuralları kodu
_logger.Log("Ödeme Yapıldı");
}
}

Yukarıdaki örnekte ILogger tipindeki işi sadece log almak olan bir sınıfın referansını, PaymentManager sınıfına, constructordan parametrik olarak geçtik. Burada hem loglama ile ilgili kodlamayı PaymentManager gibi görevi bambaşka birşey olan bir sınıf içinde yazmadık hem de bu sınıfı loglama sınıfından tamamen bağımsız hale getirdik. Yani artık aynı görevi yapan başka bir loglama sınıfını da buraya verip istersem başka bir ortama loglama yaptırabilirim.

Dependency Injection yöntemi işinize bağlı olarak birçok şekilde kullanılabiliyor. Enjekte edeceğiniz sınıfı constructor’dan veya fonksiyon’dan parametre geçebilir, mevcut sınıfa property olarak tanımlayabilir veya mevcut sınıfın atasına property olarak tanımlayabilir ve bu şekilde kullanabilirsiniz.

DI, en çok TDD (Test Driven Development) yöntemleri ile birlikte kullandığımız bir yöntem. Özellikle test edeceğimiz kısmı, rahat test edebilmek için diğer kısımlardan izole ediyoruz. Ayrıca dışarıdan o tipte herhangi başka bir sınıf da enjekte edebileceğimiz için Mock veya Fake denilen yapılar ortaya çıkmış. Yani daha henüz Logger sınıfı yazmadınız fakat bunun görevini yapan sahte bir sınıfı içeri verip Logger gibi davranmasını sağlayıp, işin o kısmıyla uğraşmıyorsunuz. Test etmeniz gereken yeri test edip daha sonra uygulama zamanında gerçek logger sınıfınızı enjekte ediyorsunuz. Böylece testleriniz daha hızlı çalışıyor. TDD’de her yaptığınız değişiklikte bütün testleri çalıştırmanız gerektiği için bu önemli. Fakat bu başka bir blog’un konusu.

Toparlayıp birer cümlede bu iki kavramı aşağıdaki gibi tanımlayabiliriz;
Polymorphism: Aynı özellikleri ile bir ataya bağlayabildiğimiz sınıfların ortak özelliklerini, başka bir kod parçası içinde, aynı tipe aitmiş gibi o atadan türeyen bütün sınıflar için kullanabilmek.
Dependency Injection: Bir sınıfın içindeki görevleri mantıklı parçalara ayırarak, bu parçaları o sınıfa dışarıdan polimorfik bir yapıda parametre olarak geçebilmek ve böylece bağımlılığı ortadan kaldırmak.

Kısaca Polymorphism ve Dependency Injection kavramlarını anlatmaya çalıştım.

Run an application if it’s not already running

Today we had a problem about an old Windows XP machine, running a 3rd party executable file. The executable sends info to a light board. Digging into problem I figured out that executable file is stopping with client interaction or by itself from time to time.

What we needed is to check if the app is running constantly. If it has been stopped we should run it. The process is not hanging so we don’t need anything there. Also the machine’s OS is old so we needed something other than WMI or PowerShell. I didn’t waste time to check if those are running on XP or not.

Here is how i solved it;

First I looked up for a batch file to do that and I came up with this thanks to Stack Overflow;

tasklist /FI "IMAGENAME eq TOTALCMD.EXE" /FO CSV &gt; search.log</code>

FOR /F %%A IN (search.log) DO IF %%~zA EQU 0 GOTO end

cd "C:\TotalCMD"
start TOTALCMD.EXE

:end

del search.log

I tested it with good old TOTALCMD.EXE. You can test this with your executable. It’s pure DOS.

Then I feel like unhappy with the unnecessary log file I created etc. Then I coded a small Console Application and compiled it with .NET 2.0.

Here is the code:

        static void Main(string[] args)
        {
            if (args.Length != 2 || string.IsNullOrEmpty(args[0]) || string.IsNullOrEmpty(args[1]))
            {
                Console.WriteLine(@"Rerun Process
Usage: RERUNPROCESS.EXE [EXECUTABLENAME] [PATH]
");
                return;
            }

            Process thisProc = Process.GetCurrentProcess();
            if (!IsProcessOpen(args[0].ToLower().Replace(".exe", "")))
            {
                StartProcess(args);
            }
            else
            {
                Console.WriteLine("{0} Process Is Already Running", args[0]);
            }
        }

        private static void StartProcess(string[] args)
        {
            Process p = new Process();
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.FileName = Path.Combine(args[1], args[0]);
            try
            {
                p.Start();
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error Rerunning {0}\n{1}", Path.Combine(args[1], args[0]), ex.Message);
            }
        }

        private static bool IsProcessOpen(string name)
        {
            foreach (Process clsProcess in Process.GetProcesses())
            {
                if (clsProcess.ProcessName.ToLower().Contains(name))
                {
                    return true;
                }
            }
            return false;
        }

What this app does is pretty straightforward. It checks for the app name in processes. If not exits, it tries to run it. I used System.Diagnostics.Process to create a new process and redirect output to that process.

Process.GetProcesses() gets all the running processes. Here is the usage if you are not happy with it or want to alter it. http://msdn.microsoft.com/en-us/library/1f3ys1f9.aspx

You can call the program like the example below;

RerunApp [Executable] [Path]
RerunApp “MYAPP.EXE” “C:\My Folder\My App\”

You can schedule it with windows task manager with the parameters you want and almost have Windows Service like behavior in old systems when running 3rd party executable files.

Here is the source; https://github.com/serkanberksoy/RerunApp

Happy Coding 🙂

Delete All Your Yahoo Mail with AutoIt

UPDATE – I tried to cleanup my yahoo mail recently. They fixed the problem with the new interface. You can scroll down and select all messages. Then do what you want with them like moving to another folder or deleting.

Yesterday I had a problem. Yahoo didn’t allow me to delete all mail in a folder.

I had 20k mail in my old Customers’ folder. I redirected all application system warnings to my yahoo mail and I forgot to maintain it. After a year it was like 20k of mails. I tried everything to delete those mails by filtering etc. but Yahoo wouldn’t bend to my will. So I thought there should be another solution and I decided to do it with brute force.

There is a great application called AutoIt. I used it once to automate some UI tasks and develop automated tests. It provides you a scripting language that you can pretty much automate anything that you do with your mouse and keyboard.

You can download it here;
http://www.autoitscript.com/site/

Also there is an AutoItRecorder application to record your mouse moves and key presses, then save all recording session as an AutoIt script. You can download it here;
http://sourceforge.net/projects/autoit-recorder/

Note: The shortcut for autoit-recorder launches an error but you can go manually to C:\Program Files (x86)\INET-Consulting\AutoIT-Recorder

So here is how I use both apps together;

1. Run autoit-recorder and do what you want to do. CTRL+BREAK to stop recorder.

autoit-recorder

2. Save your script to a file, it creates a large file, which every mouse coordinate recorded in it.

3. Right click to script file and select Edit Script. This opens the cute Auto-It editor. You don’t need another editor, Auto-It editor is great for these kind of operations. Also you can test your script by hitting F5 and stop by CTRL+BREAK in the editor.

4. So, you got large record file with lots of mousemove(x, y) coordinates. You actually don’t need all the coordinates to run this script. So find out lines like where the MouseDown(“left”) code exists. These are the lines that you actually click something. Also the first line with MouseMove command above this MouseDown line is the line that your final destination is. You only need these to go somewhere and click something on the screen. The other MouseMove lines between MouseDown commands may be deleted.

5. Also you may need to put some delay between MouseMove, MouseDown and other methods. If it’s a web page that you are automating your task, it may not respond your next move. We do it with putting a sleep command in between MouseMove and MouseDown methods.

Sleep (500) -> 500 is default that I use as milliseconds. But if I need to wait for a web page to reload I use at least Sleep(5000) (5 seconds) depending on the web page performance.

Here is my code for deleting yahoo mail. It works on Chrome browser with 1920 x 1080 resolution. You may change $pageCount variable for your need. Currently it deletes 70 pages of mails.
What my script does is straighforward. It deletes all mail page by page. To do that; first goes to checkbox at the upper left corner, clicks it. Then goes to delete button and clicks it. Goes to OK button and clicks it. Waits for 5 seconds. When page updates, it scrolls 2 lines down, so it presses Home key to keep coordinates intact. After that it goes and clicks to next page.

– Remember it deletes ALL mail in that folder. So be careful. I am not responsible if you delete wrong mail.
– If you have different resolution, different browser etc. You need to record your script or alter the coordinates below. 

dim $i
$i = 0

dim $pageCount
$pageCount = 70

While($i < $pageCount)
   MouseMove(196, 193)
   Sleep (500)
   MouseDown("left")
   MouseUp("left")
   Sleep (500)

   MouseMove(210, 173)
   Sleep (500)
   MouseDown("left")
   MouseUp("left")
   Sleep (500)

   MouseMove(796, 596)
   Sleep (500)
   MouseDown("left")
   MouseUp("left")
   Sleep (5000)

   Send("{HOME DOWN}")
   Send("{HOME UP}")
   Sleep (500)

   MouseMove(1708, 199)
   Sleep (500)
   MouseDown("left")
   MouseUp("left")
   Sleep (1000)

   $i = $i + 1
WEnd

Happy Coding 🙂

What’s new in the latest NuGet 2.5 Update

Hi all,

We are all using beautiful NuGet extension on Visual Studio for a while now. NuGet is being developed by famous people like Scott Hanselman and Phil Haack. 🙂

For people who don’t know what NuGet is; NuGet is a package manager for Visual Studio, works with central package repository http://www.nuget.org. There are 12500 packages currently on the repository and generally it’s enough for your standard project needs. I mean almost every package is there. Which means no more web crawling for popular packages’ download links on the web, download and extract them to add to your project.

In Visual Studio, you can add package by right clicking to solution and select “Manage NuGet Packages for Solution”. Select “Online” from the left menu and search for package name from the right-top search box. When you find your package just click Install and tadaa, it’s done.

nuget_gallery

Back to our topic, in April 25 they’ve released the latest update. First let me tell you where to find this update; Open Visual Studio, go to Tools -> Extensions and Updates there you will find if your NuGet version needs to be updated. Or you can alternatively go to http://nuget.codeplex.com and download / install manually.

These are the what’s new items in the NuGet web site.

  • Option to overwrite content files
  • Automatic imports of msbuild targets
  • Different references per platform
  • Update All button
  • Improved project reference support for NuGet.exe Pack
  • Add a ‘Minimum NuGet Version’ property to packages
  • Dependencies are no longer unnecessarily updated during package installation
  • NuGet.exe outputs HTTP requests with detailed verbosity
  • NuGet.exe push supports UNC and directory sources
  • NuGet.exe supports explicitly-specified Config files
  • Support for C++ and WiX project types
  • Support for Mono/Xamarin projects targeting iOS, Android, and Mac
  • Package Restore improvements
    (a prototype of the new features will be available as a separate download/installation)

As for me I was waiting for performance updates. You know, when I’m not at home, NuGet package updates are always slow with the phone tethering, client’s or Starbucks’ wireless. 🙂 With this update NuGet does not update if the dependency is satisfied within the project. With that I mean if you have a package in your project lets say A V 1.0.0 and you are trying to install B which is dependant to A V 1.0.0. If repository had A 1.0.2 NuGet was trying to update A before this version. From now on A is not updated.

Also there is another update which is great for resolving package conflicts. You can now overwrite existing package files. If you are using Package Manager Console there is a new property for Update and Install-Package parameters which is FileConflictAction. You can choose whether to Overwrite to always overwrite or Ignore option to skip files. If left empty, you’ll get prompted for every file.

And there is another great feature for people like me working with old projects once in a while. When you open a (relatively) old project, got to NuGet Package Manager by right clicking the solution. Go to “Updates” at the left menu and select “All”. Now there is an “Update All” button to update all packages. So you can stay up to date with the latest version of packages you use in this project. Also keep in mind that NuGet has a cache folder in your computer under %LocalAppData%\NuGet\Cache. When you update a package it is saved into that folder and when you add the same package version into a project it is not downloaded again and again.

There are more updates listed above but for me these are the most important. Thank you NuGet team.

Yazılım Projelerinde Ürün Yöneticisi Olmak için Gerekli Özellikler

Ürün ve iş ekipleri yazılım ekiplerinin sürekli dirsek temasında çalıştığı birimlerdir. Bu yüzden bu ekiplerin yapısı biz yazılımcıları ilgilendirir çünkü az veya çok sürekli birlikte çalışırız. Unutmayın başarıya sadece iyi bir yazılımla ulaşamazsınız. Bu yazılımın bir kişi veya daha iyisi bir takım tarafından birçok yanının yönetilmesi gerekir.

Profesyonel şirketlerde yönetim, satış, pazarlama birimlerinin istekleri ürün veya iş ekiplerinde toplanır. Bu bilgiler belli bir süzgeçten geçirilir, dokümante edilir, önem sırasına göre düzenlenir, fizibilite çalışmaları analistler ve yazılım ekipleriyle birlikte gerçekleştirilerek iş planlarına dahil edilir. Birçok şirketin süreçleri aşağı yukarı bu şekildedir. Araya farklı süreçler girip çıkabilir fakat genel olarak minimum yapı bunu gerektirir. 

Ürün Müdürü veya Direktörü yönetici pozisyonları firma yönetim hiyerarşisine, dinamiklerine göre farklılıklar gösterebilir. Bir firmada CEO’ya bağlı, diğerinde CIO veya COO’ya bağlı olabilir.

Yönetim olarak bağlı olduğu birimler yazılımcıları çok etkilemese de birlikte çalışırken birbirimizi anlayabilmek için bazı noktalarda karşı tarafın teknik bilgiye sahip olmasını bekleriz. Özellikle yazılımcı dilinden anlayıp bunu iş / business diline çevirebilecek iletişimi kuvvetli kişilerle çalışmak, biriminizin beklentilerini ve sıkıntılarını anlamak, yönetime anlatmak için gereklidir.

Uzun zamandır Ürün Yöneticileri ile birebir ilişkide olan pozisyonlarda çalıştım. Fakat hiç işe alım sırasında beklentilerim sorulmamıştı. Geçen gün firmamızdaki böyle bir pozisyon için bir arkadaşımla sohbet ederken, yazılım projelerinde yönetim pozisyonundaki bir Ürün Yöneticisi’nin ne özelliklere sahip olması gerektiğini sordu ve tartıştık. Sonrasında ben profesyonel bir arkadaşımdan konuyla ilgili yardım aldım.

Kısaca yazılım projelerinde Ürün Yöneticisi Pozisyonu’nda çalışabilmek için gerekli beceri setini aşağıdaki gibi sıralayabiliriz;

– Mutlaka teknik bir bölüm mezunu olmalı.
– Analiz yeteneği gelişmiş olmalı. Sistem tasarlayan veya sistem analizi yapan 4 yıllık bölümlerden mezun olmalı.
– Geçmişte az da olsa kod geliştirmiş olmalı.
– Veri tabanı bilgisi olmalı, segmentasyon gibi konularda bilgili olmalı.
– Test teknikleri hakkında bilgili olmalı, test ekibi yönetebilmeli.
– SEO bilgisi olmalı (Genellikle web tabanlı geliştirme yapıldığını varsayarak)
– İngilizce bilgisi olmalı ki yukarıdaki konuları ve mesleki gelişmeleri ilgili forum, site vs.’den takip edebilmeli.
– Proje yönetim yetenekleri gelişmiş olmalı ki, yazılım birimlerinden istediği işi planlayabilsin ve yetiştireceği zamanı ayarlayıp öngörebilsin.
– Diğer yandan işi ve gereklerini iyi bilmeli ki, bunları yazılımcıların anlayabileceği bir dille ifade edebilsin.
– Ortaya çıkan ürüne Prod OK verebilecek ve bunun sorumluluğunu alabilecek deneyime sahip olmalı.
– Dokümantasyon ve yazılı iletişim açısından kendini sözel ve yazılı olarak ifade etme yetenekleri çok iyi olmalı. Özellikle yazılım projelerinde istek (requirement) dokümantasyonu düzgün oluşturulmadığında iş yanlış anlaşılıyor, tekrar yapılmak zorunda kalıyor ve maliyet çok yükseliyor.
– Dolayısıyla İngilizce, teknik bilgi, kendini ifade edebilme yetenekleri kuvvetli olmalı.

Evet farkındaysanız yukarıda Pazarı bilmesi vs. gibi konularda detaya girmedim. Eminim bu pozisyonun daha detaylı tanımı IK Profesyonelleri tarafından yapılabilir. Benim bir bilişim profesyoneli olarak başarılı proje yürütebilmek için birlikte çalışacağım Ürün Yöneticisi’nden veya ekibinden beklediğim gereksinimler bu şekilde.

Gördüğünüz gibi doldurulması zor bir pozisyon ve Türkiye’de bu kalibrede ürün yöneticileri özellikle ilgili sektörün içinden zor bulunuyor. Genelde bu pozisyona yönelik bölümler yerine sektörde kendini geliştirmiş, tecrübe kazanmış kişileri Ürün Yöneticisi pozisyonunda görebilirsiniz. Yani yazılım projeniz finans sektöründeyse finansın içinden gelen pozisyonlar Ürün Yöneticisi olarak yönetim kadrosuna yükseliyor. Bu durumlarda genelde yukarıdaki beklentiler karşılanmıyor ve yazılım ekipleriyle koordinasyon yeterince kuvvetli olmuyor.

Peki sektörel tecrübesi çok kuvvetli olan bir Ürün Yöneticiniz var. Onunla yolları ayırmak istemiyorsunuz fakat başarıya ulaşmak istiyorsunuz. Bu açıkları kapatmak için neler yapılabilir?

– Şirket bünyesinde profesyonel analistler çalışabilir ve dokümantasyon bu ekiplerin yönetiminde olur.
– Test ekipleri yazılım ve kabul testlerine destek verebilir.
– Proje süresince ve sonrasında Profesyonel SEO desteği alınabilir.
– Ayrıca bir Proje Yöneticisi pozisyonu veya proje ofisi açılıp, Ürün Yöneticisi PMI’ın öngördüğü gibi “Proje Şampiyonu” olarak kullanılabilir.

C# öğrenmek için doğru linkler

Uzun bir aradan sonra herkese merhaba,

Öncelikle ilgilenip mail atan arkadaşlara teşekkür ediyorum. Genelde benzeri sorular geldiği için aşağıdaki derlemeyi yapma ihtiyacı doğdu.

C# öğrenirken dil şart demiştik o yüzden genelde yabancı kaynak takip ediyorum. Yeni başlayan arkadaşlar için de aşağıdaki kaynakları öneriyorum. Kitabın içinde de özellikle terimlerin İngilizce isimlerini kullanarak sizi araştırma yaparken rahatlatmaya çalıştım. Aklıma geldikçe veya sizden geldikçe bu sayfayı güncelleriz.

– HeadFirst yayınları sıfırdan başlayanlar için çok iyidir. Anlatımı akılda kalıcıdır. Özellikle Object-Oriented, Design Patterns ve Java kitabını (Java yazmayacak olsanız bile) tavsiye ederim. Burası bittikten sonra Wrox veya APress veya O’Reilly yayınlarına geçilebilir. Bu yayınları C# başlığı altında geçen kitapları alınabilir.

Burada bu kitapların içeriğinden çok, sizin için okuması hangisi kolaysa onu seçmenizde fayda var. Okuması kolay ile  kastım sayfa düzeni ve fontları. Bunu kitabı almadan önce Amazon.com’dan kitabın içine göz atarak görebilirsiniz.

– Ayrıca Pluralsight video’larını mutlaka inceleyin. Burada, kitapta atladığınız noktaları görsel olarak tamamlayacabileceksiniz.

– Yukarıdakileri bitirdikten sonra ASP.NET, Win Forms, MVC, Silverlight, WCF vb. hangi teknolojiyi kullanacaksanız bu başlıkta bir kitap alabilirsiniz.

– Son olarak konuyu öğrendikten sonra web’den her zaman en geniş örneklere ulaşabilirsiniz. Burada kullandığımız iki büyük site var. Mutlaka araştırırken karşınıza gelecektir fakat ben yine de yazayım.

– http://www.codeproject.com/

Codeproject sitesinden konu ile ilgili anlatım ve baştan aşağı bitmiş, çalışan örneklere ulaşabilirsiniz.
Stackoverflow sitesinde ise mutlaka sizin karşılaştığınız problemi başkası sormuş ve genelde yazılım camiası da cevaplamış olacaktır.

Sevgiler,
Serkan Berksoy

Erişim Bilgilerim

Herkese merhaba,

C# Tam Hakimiyet ile ilgili yorumlarınız için teşekkür ederim.
Ayrıca yayınlayabildiğim ve yayınlayamadığım sorularınız ve ilginiz için teşekkürler.

Yoğunluğum sebebiyle uzun zamandır yeni blog girişi yapamadım.
Bana homeofserkan@gmail.com adresimden erişirseniz sorularınızı yanıtlamaya çalışırım.

Serkan Berksoy

C# Tam Hakimiyet Yayında

Hepsi Burada Linki:
http://www.hepsiburada.com/Liste/c-tam-hakimiyet/ProductDetails.aspx?productId=kdikeyeksen58834&categoryId=211651 

D&R Linki:
http://www.dr.com.tr/0000000350708,0000000374912/Eser/Kitap/Egitim-Basvuru/Bilgisayar/C#-Tam-Hakimiyet

İdefix linki
http://www.idefix.com/kitap/c-tam-hakimiyet/tanim.asp?sid=SP1JVCITPT2HBLSSY3JH

Kitap Yurdu linki
http://www.kitapyurdu.com/kitap/default.asp?id=588665&sa=91736957