Visul Studio Kod Metrikleri (Code Metrics)

Kod metrikleri, Visual Studio içinde yer alan kaynak kodları incelemek ve çeşitli ölçülere göre yazılımı derecelendirmek için kullanılan matematiksel ve istatistiksel yöntemlerdir. Kod metrikleri, bir projenin sınıflarını, modüllerini ve namespacelerini, çeşitli ölçülerle değerlendirerek potansiyel sorun kaynaklarını vurgular.

  • Lines of Code
  • Class Coupling
  • Depth of Inheritance,
  • Cyclomatic Complexity
  • Maintainability Index

Kod Metrikleri, Solution Explorer’da bir projeye veya solution üzerine sağ tıklayıp “Calculate Code Metrics” diyerek veya Analyze menüsünden “Calculate Code Metrics For Solution / Project” ile hesaplanabilir.

Codemetrics

Lines of Code

Lines of Code, bir metoddaki işletilebilir kod satır sayısını gösterir. Alfabe dışı karakterler, commentler, tip ve namespace tanımları bu hesaplamanın dışında kalır. Çok yüksek bir değer, bir tipin veya metodun çok fazla iş yaptığı, bu yüzden de bölünmesi gerektiği anlamına gelir.

Lines of code

Class Coupling

Bu metrik; sınıf seviyesinde, parametreler, yerel değişkenler, dönüş tipleri, method çağırımları, generic ilklemeler, base sınıflar, arayüz implementasyonları vb. aracılığıyla diğer sınıflarla olan bağlantı sayısını ölçer. Kısaca bu metrik bir sınıfın bağlı olduğu sınıf sayısını gösterir. Bu sayının mümkün olduğunca az olması beklenir. Çünkü yüksek coupling değerleri, bir tasarımın diğer sınıflara bağımlılıkları yüzünden, yeniden kullanılmasının ve bakımının güç olduğu anlamına gelir.

classcoupling

Depth of Inheritance

Kalıtım derinliği, bir sınıfın, kalıtım ağacında o sınıfın üst düğümünden köke kadar olan sınıfların sayısını gösterir. Hiyerarşi ne kadar derinleşirse, hangi metodların veya alanların nerelerde tanımlandığını veya yeniden tanımlandığını takip etmek de zorlaşır. Çok derin kalıtım ağaçları, uygulamanın testinin ve bakımının karmaşıklığını arttırır.

Depth of Inheritance

Cyclomatic Complexity

Cyclomatic Complexity programdaki birbirinden farklı kod akışlarının sayısıdır. Daha basitçe açıklamak gerekirse, programdaki karar noktaları olan if bloklarının, do, while, foreach ve for döngülerinin ve switch case bloklarının sayısıdır. Yüksek cyclomatic completixy değerine sahip olan kodların test ve bakımı zor olmaktır. Çünkü bu kodlarda test edilebilecek çok sayıda farklı akış vardır.

Cyclomatic Complexity

Cyclomatic Complexity(CC) değerini hesaplamak için aşağıdaki gibi basit bir yol izlenebilir.

  1. Metodun akışına CC= 1 değeri ile başla.
  2. Her bir if,while,repeat, for, and , or anahtar kelimeleri veya eşdeğerleri için CC’ye 1 ekle
  3. Switch’teki her bir case için CC’ye 1 ekle

Metodlar için cyclomatic complexity değerleri ve riskleri belirtilmiştir. Cyclomatic complexity değeri ne kadar yüksekse metodun karmaşıklığı da o kadar fazladır.

cyclomatic complexity tablo

Maintainability Index

Sınıf üyeleri veya tipler seviyesinde kod bakımının kolaylığına gösteren bu değişken 0-100 arasında bir değer alır. Bu değerin yüksek olması programın sürdürebilirlik seviyesinin yüksek olduğu anlamına gelir. Namespace veya assembly seviyesindeki maintainability index, o namespace veya assembly içerisindeki bütün tiplerin maintainability indexlerinin ortalamasıdır. Bu metrik, Halstead Volume, Cyclomatic Complexity ve Lines of Code metrikleri bir araya getirilerek oluşturulmuştur. Halstead Volume, kullanılan işlenen (operand) ve işlemcilerin (operator) sayısıyla ilgili bir metriktir. Maintainability index için kullanılan denklem aşağıda verilmiştir.

—MI = 171 – 5.2 * log2 (HV) – 0.23 * (CC) – 16.2 * log2 (LOC)

—HV: Halstead Volume
—CC: Cyclomatic Complexity
LOC: Lines of Code

Maintainability index, kolay bir gösterimi olması için ikonlarla ifade edilmiştir. İkonlar için, değer aralıkları ve sürdürebilirlik seviyeleri aşağıdaki gibidir.

maintainability index

Alıntıdır.

https://sametbulu.wordpress.com/tag/metrik/

C# statik method kullanımları

class Program
{
    static void Main(string[] args)
    {

        var list = new List<int>(){0,2};
         
        //1.Yol
        Mex.M2(list);

        //2.Yol
        list.M2();


        list.M3();//this tanımlaması olmadıı için erişim sağlanamaz.
    }
}

public static class Mex
{
    public static void M2(this List<int> list)
    {
        Console.Write("test");
    }


    public static void M3(List<int> list)
    {
        Console.Write("test");
     }


}

static methodlara direk erişim sağlanabilir. Method içerisinde this ile tanımlama program içerisinde . ile belirtilen tip için method çağırımı yapılabilmesini sağlamaktadır. Ör: list.M2();

.NET Lazy sınıfı kullanımı

Lazy sınıfı ile ihtiyaç duyduğumuz verinin ihtiyaç anında erişilebilmesi veya yapılacak işlemin ihtiyaç anında yapılması gibi durumlarda kullanabileceğimiz bu sınıf ile performans konusunda projenize katkı sağlayabilirsiniz.

IsValueCreated property ile objenin yaratılıp yaratılmadığını kontrol edebiliriz.
Value özelliği ise T generic tipimizi temsil etmektedir. Value özelliğine eriştiğiniz an T tipi Activator tarafından Create edilmektedir fakat eğer Constructor‘a Func ile uyuşan bir metod verirseniz o metod Value özelliğine erişmeye çalıştığınızda tetiklenecek.

Alıntıdır.
http://www.muratoner.net/csharp/net-lazy-sinifi-nedir-ve-neden-kullaniriz

c# var, dynamic, object farkı

dynamic ile object Tipleri Arasındaki Fark

dynamic ile object arasındaki en temel fark, derleme zamanındaki tip uyumsuzluğu kontrolüdür. Bildiğiniz üzere object tipini kullanabilmemiz için unboxing (kutudan çıkarma) yapmamız gerekiyor. Yani bir tip object olarak tanımlanmışsa, karşı tarafta bunun tipinin ne olacağını belirtmeliyiz
Fakat dynamic tipi için böyle bir işleme gerek yok. dynamic tipler derleme sırasında hata almazken, object tipler için ise unboxing yapmalı, tipini açıkça belirtmeliyiz. Kısaca dynamic tipler bizi derleme hataları zahmetinden kurtarmaktadır. Fakat dynamic tipler her zaman güvenli bir program sunmayabilirler. Dikkatli kullanılmadığında çalışma zamanı hatalarına yol açabilirler. Bundan dynamic tipleri kullanmaktan kaçınmalıyız anlamı çıkarılmamalıdır. Tam tersine dynamic tip kullanımı bazen oldukça elverişli ve gerekli olabilmektedir.

var Anahtar Sözcüğü

dynamic tipleri anlatıp var tipinden bahsetmemek olmazdı. var tipi de tıpkı dynamic tipler gibi herhangi bir tipte bir değişken değeri olabilir. Temel düzeyde javascript biliyorsanız javascriptteki var tanımlayıcısıyla çok benzerlik gösterir. Peki aralarında ne gibi farklar var?

var ile dynamic Tipler Arasındaki Farklar

Yukarda var tipinin de değişken tiplerde değer alabildiğini ifade etmiştik. dynamic tiplerden bazı farklarla ayrılır. dynamic tipler null olabiliyorken var tipleri mutlaka bir başlangıç değerine sahip olmalıdır. Ayrıca ilk atanan tip neyse program sonlanana kadar aynı tipte olmak zorundadır. Bunu bir örnekle açıklayalım.

Asp.Net HTTPModule ve HTTPHandler

ASP.NET iş akış süreci, gelen bütün isteklerin ASP.NET tarafından iş akışı üzerinde bulunan birimlere (module) iletilmesiyle başlar. Her birim gelen isteği aldıktan ve istek üzerindeki tüm yetkiyi elde ettikten sonra, en uygun hale gelinceye kadar istek üzerinde işlem yapar. İstek bütün HTTPModule yapılarından geçtikten sonra ilgili HTTPHandler’a iletilir. HTTPHandler istek üzerinde bazı işlemler yaptıktan sonra, isteğe verilen cevap ASP.NET iş akışında isteğin geldiği HTTPModule yapıları aracılığıyla iletilir.

ASP.NET Runtime tarafından gelen isteklerde birden fazla HTTPModule kullanılmasının sebebi, Web uygulamalarında kullanılan Cache (ara belleğe alma), Session (kullanıcı tarafından oluşturulan oturum), Authentication (kimlik doğrulama) nesnelerinin her biri için farklı bir HTTPModule kullanılıyor olmasıdır. HTTPHandler ise HTTPModule yapılarından gelen bilgileri kullanarak uygun html çıktısını üreterek aynı HTTPModule yapıları üzerinden ASP.NET Runtime’a iletilir.

Daha detaylı anlatım için URL;

http://bidb.itu.edu.tr/seyirdefteri/blog/2013/09/08/httpmodule-ve-httphandler

REST Apilerde Dönülen HTTP Status Kodları (Yaygın Kullanılanlar)

HTTP statuslarını gruplayacak olursak;
Bilgilendirme – 1xx
Başarılı İşlem – 2xx
Yönlendirmek – 3xx
Kullanıcı Taraflı hata – 4xx
Server Taraflı hata – 5xx

200 OK: Genelde veri listeleme sonuçları 200 ile dönüş yapılır.
201 CREATED: Veri eklendiği zaman verinin kendisi ile 201 dönülüyor.
204 NO CONTENT: Veri silindiği zaman 204 dönülüyor.
400 BAD REQUEST: Genel olarak kayıt ekleme ya da güncelleme isteklerinde gönderilen veri validasyondan geçemediyse neden geçemediği hakkında bilgiyle beraber 400 http statusuyla dönülür.
403 Forbidden: Yetkiye dayalı bir işlem yapılıyorsa bu api uç noktasında işlem yapmaya çalışan kişinin bu işlemi yapmaya yetkisi yoksa 403 status kodu döndürülür.
401 Unauthorized: Api ucunuzda bu işlemi yapmak için login olmak zorunlu ise ve apiye istek yapan kullanıcı login değil ise bu http status ile cevap verilir. Örneğin kullanıcının kendi bilgilerinin güncellemesi denilebilir.
404 Not Found: Bu http status  kullanıcının istek yaptığı url yok ise ya da url deki veri geçersiz ise bu hatayı alırız.
405 Method Not Allowed:
 Bu http status u istek yapılan api uç noktası gönderilen methodu implemente etmemiş ise bu http status unu alırız. Örneğin login olması için token verdiğimiz bir api ucumuz var ve bu uçta sadece post isteğini kabul ediyor. Kullanıcı bu api urline GET isteği yaparsa bu hatayı alır.

429 Too Many Requests: Bu http statusunu saatlik ya da dakikaklık kısıtlanan sınırdan fazla istek yaparsak bu http statusunu alırız.

C#’ın fazla bilinmeyen bir kaç özelliği

1. Değişken isimlerinde @ karakteri ile rezerve isimler kullanılabilir
Değişkenin önüne @ işareti koymanız yeterli:

private string @string;

2. “default” ile generic tiplerde varsayılan değerin atamasını sağlayabilirsiniz.
T referans tipiyse null, int ise 0, boolean ise false atanacaktır.

T t = default(T);

3. Dosya yollarını “System.IO.Path.Combine()” ile birleştirebilirsiniz.

string fullPath = mainPath + "\\" + fileName;
//Yerine 
string fullPath = System.IO.Path.Combine(mainPath, fileName)

4.“Environment.NewLine” yeni satıra geçmek için gereken “escape karakteri”ni döndürür.

Uygulamanın çalıştığı ortamda yeni satır karakteri neyse Environment.NewLine bu karakteri döndürür. Böylelikle ortamdaki yeni satır karakteri “\n” miydi “\r\n” miydi diye kara kara düşünmemize gerek kalmaz!

5.“Coalescing operator” ile kolay null kontrolü
Aşağıdaki örnekte, test string’ine testStr1‘in değeri null değilse atanacak, şayet null ise testStr2 atanacaktır. Eğer testStr2 de null ise boş string ataması yapılacaktır. (Deneyerek görmeniz, bu cümleleri okuyup anlamanızdan çok daha kolay olacaktır gibi geliyor bana

string test = testStr1 ?? testStr2 ?? string.Empty

6. yield iterasyon oluşturmak için kullanılır.
Compiler yield anahtar sözcüğünü gördüğü anda bu keywordün bulunduğu bloğun bir iterator bloğu olduğunu algılamaktadır. Bu adımdan sonra foreach döngüsü içerisinde ilgili koleksiyonu dönen metod çağrıldıktan sonra metod içerisindeki bir yield return ifadesine gelinince değer geriye dönülmekte ve bu işlem yapılmadan önce Compiler, iterator metodun kaldığı yeri saklamaktadır. Süreç esnasında foreach döngüsünde iterator metoduna gelen her istekte iterator metot baştan başlamak yerine kaldığı yerden işletilmektedir.
yield anahtar sözcüğünü aşağıdaki gibi iki farklı şekilde kullanabilmekteyiz.

yield return [value]
yield break

“yield return [value]” kullanımı ile yukarıdaki örneklendirmemizde olduğu gibi çalışabilmekteyiz. Lakin “yield break” ifadesi ile iterator içerisindeki iterasyonun sona erdiği bilgisi ilgili foreach döngüsüne bildirilmektedir. Aşağıdaki kod parçacığı bu durumu örneklendirmektedir.

static public IEnumerable VerileriGetir()
{
    yield return "Pazartesi";
    yield return "Salı";
    yield return "Çarşamba";
    yield return "Perşembe";
    yield return "Cuma";
    yield return "Cumartesi";
    yield break;
    yield return "Pazar";
}

static void Main(string[] args)
{
    foreach (var Gun in VerileriGetir())
        Console.WriteLine(Gun);
 
    Console.Read();
}

“yield break” ifadesinden dolayı ilgili foreach iterasyonun sona erdiğini bilecek ve “Pazar” değerini yazdırmayacaktır.
Son olarak, yield keywordü kullanılan iterator bir metot, foreach için evaluate edilmediği sürece yield komutu ilgili metodu çalıştırmayacaktır.
Yani VerileriGetir() değerlerini bir değişkene atarsak sadece methodu referans göstermiş oluruz, Method içerisine sadece döngü esnasında girecektir.

static void Main(string[] args)
{
    IEnumerable Veriler = VerileriGetir();
 
    foreach (var item in Veriler)
        Console.WriteLine(item);
}

Bu örnekte “Veriler” değişkeninin içinde foreach döngüsüne gelmeden önce hiçbirşey olmayacaktır. Ne zaman ki döngüye girilecek, o zaman VerileriGetir metodu çalıştırılacaktır. Yani istemci tarafından ne zaman foreach döngüsüyle çağrılırsa bir anlamda yield lazy loading yapmış olacaktır.

Visual Studio Publish exclude etme(publishte klasör ve dosya gizleme)

Bazen publish esnasında tüm dosyları canlıya geçerken hepimizin yaptığı gibi webconfig gibi db adreslerimizi ve bazı local ayarlarımızı gösteren dosyaları yanlışlıkla servera kopyalayabiliriz. Bu durumun önüne geçmek için publishten config dosyalarını gizleyebiliriz. Bunun için aşağıdaki gibi Visual Studio Projesi içerisinde\Properties\PublishProfiles\projeadi.pubxml dosyasını düzenleyebiliriz.

 

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
.......
<!--publish ile çıkarılmaması istenilen klasörleri buraya ; ile yazabiliriz -->
<ExcludeFoldersFromDeployment>Folder1;Folder2</ExcludeFoldersFromDeployment>
<!--publish ile çıkarılmaması istenilen dosyaları buraya ; ile yazabiliriz -->
<ExcludeFilesFromDeployment>LocalConnectionStrings.config;</ExcludeFilesFromDeployment> 
</PropertyGroup>
</Project>

Delegate kullanımı

Delegate’ler bir metodun referansı olarak kullanılırlar. Dolayısı ile nesneleri heap’de durur. FIFO Mantığıyla çalışır.

    delegate int Matematik(int x);
    delegate void MyGenericDelegate(T args); //generic delegate
    class Program
    {
        static void Main(string[] args)
        {
            //generic delegate
            MyGenericDelegate stringDelegate = new MyGenericDelegate(StringTarget);
            stringDelegate("Safak");

            MyGenericDelegate intDelegate = new MyGenericDelegate(IntTarget);
            intDelegate(26);

            //Aşağıdaki list ile Delegenin üzerindeki metotları görebiliriz.
            Delegate[] DelegeMetodListesi = stringDelegate.GetInvocationList();

            //Action - Void türü methodlar için kullanılır, geri sonuç döndürmez.
            Action<int,string> action = new Action<int,string>(DisplayAge);
            action(28,"CEM");

            //Func - Geri değer döndüren methodlar için kullanılır.
            Func<DateTime, double> func = new Func<DateTime, double>(GetUserAgeAtTime);
            double dateDif = func(DateTime.Now.AddYears(-2));
            Console.WriteLine("\nDate Dif: {0}", dateDif);

            //Delegate
            Matematik canta = new Matematik(KareAl);
            canta += new Matematik(KupAl); // delege ekleme
            canta -= new Matematik(KareAl); // delege çıkarma
            Console.WriteLine(canta.Invoke(5)); //delege çalıştırır.

            int delegesonu = canta(3); //delege çalıştırır(canta.Invoke(3) aynı işi yapar).
            Console.ReadKey();
        }

        static double GetUserAgeAtTime(DateTime birthDate)
        {
            return (DateTime.Now - birthDate).TotalDays;
        }

        static void StringTarget(string arg)
        {
            Console.WriteLine("arg in uppercase is: {0}", arg.ToUpper());
        }
        static void IntTarget(int arg)
        {
            Console.WriteLine("++arg is: {0}", ++arg);
        }
        static void DisplayAge(int age, string name)
        {
            Console.WriteLine("Name: {0}, Age: {1}", name, age);
        }

        static int KareAl(int sayi)
        {
            return sayi * sayi;
        }

        static int KupAl(int sayi)
        {
            return sayi * sayi * sayi;
        }

    }

WSDL(Web Services Description Language) Nedir ?

WSDL, XML tabanlı web servisleri tanımlamak ve yerini belirtmek için tanımlanmış dildir. WSDL, W3C standardıdır. Bir anlamda dağıtık programlamada kullanılan IDL’e (Interface Definition Language – Arayüz Tanımlama Dili) benzer. Web servisi tanımlı işlemler, giren ve çıkan mesaj formatları, ağ ve port adresleri gibi bilgileri tanımlar. Bir web servisi tanım belgesi aşağıdaki temel elemanları içerir:
Types: mesajlarda kullanılacak veri tiplerini belirtir.
Message: İletişimde kullanılacak mesajları tanımlar.
PortType : Web servisinin içerdiği işlemleri (methods) ve ilgili mesajları tanımlar.
Binding : İşlem ve mesajlarda kullanılacak veri formatlarını tanımlar.
Port: Binding ve web adresinden oluşan servis noktasını tanımlar. Web adresi servisin çalıştırılacağı URL’dir.
Service: Kullanılan port’lar kümesidir.