Programcılıkta isimlendirmenin önemi

7 Ağu

Bu blog yazıma konu olarak programcılıkta isimlendirmenin önemini seçtim ancak mesele aslında bir kitap yazdıracak kadar mühimdir. Hatta bu konuyu kitaplarına konu almış programcılar da mevcuttur.

Bilgisayar bilimine yıllarını vermiş kişilerden bu konunun aslında zorlayıcı bile olduğunu duyunca insan bir kez daha durup düşünüyor. Phil Karlton şu sözlerle isimlendirmenin zorluğundan bahsetmiştir: “There are only two hard things in Computer Science: cache invalidation and naming things”. Yani bilgisayar biliminde en zor iki şeyden biri isimlendirmelerdir.

Bilgisayar bilimine programlama branşı açısından baktığımızda mimari tarafında, kodlama sırasında ve veri tabanlarında yapılan isimlendirmeler, bir sistemin anlaşılabilir olması açısından çok önemlidir. Anlaşılabilirliğin sağlanması için programcılar olarak niyetimizi ortaya koyan isimlendirmeler yapmalıyız. Doğru isimler bulmak, iş modeline göre veya sistemin büyüklüğüne göre zorlaşabilir. Yazılım ve mimari genişledikçe verilen isimler birbirine benzemeye başlayabilir. Benzerliklerin artması ise kafa karışıklığına yol açar.

Doğru isimleri bulduğumuzda ise dikkat etmemiz gereken bir diğer husus, okunabilirlik kurallarına uymaktır. Yani yazdığımız isimler okunuş açısından gözü rahatsız etmemeli ve kısaltmalardan arındırılmış olmalıdır.

Oluşturulan sistemin her elemanına verilen isim özenle seçilmelidir. Sistemin elemanı bir mimari katman olabileceği gibi bir sınıfa ait bir üye de olabilir, bir veritabanı tablosu da olabilir.

Kendi tecrübelerim adına söyleyeyim, kodlama sırasında sınıflara veya sınıf üyelerine verdiğim isimler kafamda oturuncaya kadar onları birçok kez yazıp değiştirdiğim olur. İsmiyle özdeşleşmeyen nesnelere kafayı takarım desem hiç yanlış olmaz. Bu alışkanlığa nereden kapıldığımı da söyleyeyim, ta ki programlamada isimlendirme teamüllerini (Naming Conventions) okudum ve uygulamaya başladım, bu alışkanlık o gün bugündür benimle beraberdir. Aslında bu şikayet ettiğim değil sevindiğim bir durumdur. Alışkanlıklarım kodlama ile başladı, proje isimleri ile devam etti, veritabanı tablo isimleri derken dosya isimlerini bile özenle seçer hale geldim.

Programcılıkta isimlendirme meselesine gerçekten dikkat edilmesi gerekir. Çünkü isimlendirme, programcılıkta artık bir standart halini almıştır. İşin üstatları olarak bilinen birçok programcı buna dikkat ediyor. Önder yazılım firmaları ve programcıların oluşturduğu açık kaynak(open source) kodları açıp incelediğimizde bunu rahatlıkla görebiliriz. Amacının dışında bir isimlendirmenin olmadığını hemen fark edebiliriz. Düzenli ve sistemli bir çalışmanın isimlendirmelere de yansıdığını hemen anlayabiliriz. Yani isimlendirme kuralları düzenli, okunabilir ve anlaşılabilir sistemler için bir standart olmuştur.

Eğer standartlara uygun bir Framework, API v.s yazmak istiyorsak dikkat edeceğimiz noktalardan biri isimlendirmelerdir.

İlham kaynağım:
MSND Naming Conventions
Clean Code

Prime Factors Kata C# – Kod Kata

28 Tem

Prime Factors Türkçe olarak Asal Çarpanlar şeklinde tercüme edilebilir. Prime Factors Kata’sını geliştirirken bir sayının asal çarpanlarının bulunması hedeflenmektedir. Bir sayının asal çarpanları bulunup liste şeklinde kullanıcıya verilmektedir. Aşağıdaki listede örnek olarak verilen sayıların çarpanları listelenmiştir.

Prime Factors (Asal Çarpanlar)

1 => [ ]
2 => [2]
3 => [3]
4 => [2,2]
5 => [5]
6 => [2,3]
7 => [7]
8 => [2,2,2]
9 => [3,3]
10 => [2,5]
24 => [2,2,2,3]

TFS online üzerindeki bir takım projesi nasıl silinir?

24 Tem

Microsoft’un sunduğu TFS(Team Foundation Service) sayesinde online ortamın takım projeleri(Team Project) oluşturmak mümkündür. Şimdilik 5 kişiye kadar olan takımlar için ücretsiz kullanabilen bir hizmettir. Sistemi biraz kurcaladım ve gayet başarılı bir ürün olduğunu gördüm. Şimdilik şu açıdan söylüyorum sistem üzerinde bir kaç defa proje oluşturup silerek denemeler yaptım henüz “TFS online takıldı!” diye bir mesajla karşılaşmadım. Hız konusunda yine gayet başarılı.

Gelelim bu yazımızın konusuna. TFS online üzerinde takım projesi oluşturmak çok kolay. Ancak  TFS online arayüzü üzerinden veya Visual Studio üzerinden takım projelerinizi silme hizmeti verilmemiş ya da ben göremedim. Hal böyle olunca Command Prompt üzerinden silme işlemlerini gerçekleştirdim. Silme işlemini aşağıdaki gibi adımlar halinde özetlemek istedim.

Silme işlemine başlamak için öncelikle Visual Studio Command Prompt aracını yönetici olarak çalıştırmalıyız. Komut satırına aşağıdaki düzende silme komutunu girmeliyiz. Ek bilgi olarak şunu belirteyim, bu işlemleri gerçekleştirdiğim makine üzerinde Windows 8 ve Visual Stuido 2012 mevcut.

tfsdeleteproject /collection:https://YOUR-ACCOUNT-URL.visualstudio.com/DefaultCollection "Your project name"

Yukarıdaki desene örnek olması açısından bizim kodumuzu şu şeklide yazabiliriz.

tfsdeleteproject /collection:https://rabitelli.visualstudio.com/DefaultCollection telekome
Delete Command
Delete Command

Komutu çalıştırdığımızda eğer TFS üzerinde oturum açılmamışsa oturum açma penceresi belirecektir.

Login TFS Online
Login TFS Online

Oturum açma işleminin ardından karşımıza çıkan pencerede silme işleminin sonuçlarında oluşacak durumları onaylamamız istenecektir.

Silme işlemini onyala
Silme işlemini onayla

Silme işlemi başarılı bir şekilde gerçekleşirse aşağıdaki şekilde bir pencere ile karşılaşmamız gerekmektedir.

TFS Online Silme işlemi tamamlandı
TFS Online Silme işlemi tamamlandı

Artık projemiz TFS üzerinden silinmiştir.

ArcGIS Map Server verileri ile Google Chart çizdirilmesi

22 Tem

Bir önceki yazıda ASP.NET Web API ile  tarafından servis edilen JSON verileri ile Google grafiklerinin çizimini yapmıştık. Bu yazıda da yine Google grafik çizimi üzerinde duracağız. Grafik çizimi için kullanacağımız veri ise uzak bir sunucu üzerinde elde edilecek. Uzak sunucu verileri ise ArcGIS firmasının sunmuş olduğu örnek REST servislerinden elde edilecek.

ArcGIS firmasının sunduğu örnek servislere buradan ulaşmak mümkündür. Biz bu servislerden nüfus ile alakalı olan demografik yapı servislerini kullanacağız. Demografik yapıya ait şu anda üç farklı MapServer hizmeti açılmış durumda. Biz bunlardan Demographics/ESRI_Census_USA servisi tarafından sunulan verilerle çalışacağız. USA’de bölgeler ya da eyaletler(states) adı altında sunulan Feature Layer üzerinden bir istatistik alarak örnek bir grafik çizdirmeye çalışalım. Bu örnek istatistiğimiz “2007 yılında nüfusu 9 milyondan büyük olan bölgelerin listesi.” şeklinde olsun.

Örnek uygulamamız, sunucu üzerinde çalışan tek bir HTML dosyası da olabilir, bir ASP.NET uygulaması üzerinden de çalışabiliriz. Yapacağımız şey ArcGIS Server sunucusuna bir sorgu gönderip gelen veriyi işlemek.

Feature Layer Servisi: http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer/5

Bu servise bir sorgu gönderdiğimizde gelen verinin JSON şekli aşağıdaki gibidir.

Arcgis Query Result
Arcgis Query Result

Bize grafik çizimi için gerekli olan kısım, kırmızı çerçeve içerisine alınmış features dizisidir. Bu dizi içerisinde her bir attribute, nüfus(POP2007) ve bölge adı(STATE_NAME) bilgileri bulunmaktadır. Bu bilgiler ışığında sorgulama ve çizim işlemlerini javascript ortamında aşağıdaki gibi gerçekleştirebiliriz.

<script type='text/javascript' src='https://www.google.com/jsapi'></script>
<script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js'></script>
<script type="text/javascript">

function getMap() {

   var mapserverUrl = "http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer/5/query";
   var parameters = { f: "json", where: "POP2007 > 9000000", returnGeometry: false, outFields: "POP2007,STATE_NAME" };

   $.ajax({
          url: mapserverUrl,
          data: parameters,
          dataType: "jsonp",
          jsonpCallback: "callback",
          success: function (response) {
             createGraphics(response.features);
          }
   });
 }

function createGraphics(data) {

    var table = new google.visualization.DataTable();
    table.addColumn('string', 'STATE');
    table.addColumn('number', '2007 POP');

    for (var i = 0; i < data.length; i++)
        table.addRow([data[i].attributes.STATE_NAME, data[i].attributes.POP2007]);

    var options = { title: 'Population of 2007 in the USA, Bigger than 9 Million' };
    var chart = new google.visualization.ColumnChart(document.getElementById('cbs'));
    chart.draw(table, options);
 }

 google.load("visualization", "1", { packages: ["corechart"] });
 google.setOnLoadCallback(getMap);

</script>

Yaptığımız sorgu standart bir ajax sorgusudur. parameters olarak belirlenen veri kümesi servis URL’i için queryString verilerini barındırmaktadır. Gerisi zaten Google grafik API işlemleri Bu örnek uygulamanın çıktısı aşağıdaki şekilde olacaktır.

Arcgis ve Google Chart
Arcgis ve Google Chart

Asp.Net Web API verileri ile Google Charts kullanımı

19 Tem

Farklı platformların birbiri ile konuşabilmesi biz yazılımcılar için gerçekten büyük bir nimet. Bunu ASP.NET Web API verilerini kullanarak Google Chart API grafiklerini kolay bir şekilde çizdirebildiğimde bir kez daha anlamış oldum.

Geliştiriciler için birçok kullanışlı ürün ortaya koyan Google Google Chart API uygulaması ile grafik kullanmak isteyenlere yeni bir kapı açmıştır. Platform bağımsız uygulamalar konusunda çok iyi ürünler ortaya koymaya devam etmektedir. Bende bu grafik ürününü incelerken hemen bir Web API oluşturup kullanmak istedim. Başarılı sonuca ulaşınca da bunu sizlerle paylaşmak istedim.

Örnek bir Web API uygulaması üzerinden Google Grafiklerini çizdirmeye çalışalım. Hemen boş bir ASP.NET MVC uygulaması oluşturarak işe başlayalım. Örnek uygulamamızda hedeflenen buradaki Google sütun grafiğini çizmektir. Uygulama çalıştığında ulaşacağımız grafik aşağıdaki gibi olacaktır.

ASP.NET WEB API ve Google Charts

Grafikte kullanılacak olan veri modelini aşağıdaki şekilde oluşturarak işe başlayalım.

public class CompanyReport
{
    public string Year { get; set; }
    public double Sales { get; set; }
    public double Expense { get; set; }
 }

Model sınıfımız yıllara göre satış ve giderleri veren bir özet niteliğinde olup grafikte olması gereken verileri tutmaktadır.

Şimdi de bu veri tipine uygun verileri servis edecek olan bir Api Controller oluşturmalıyız.

public class CompanyController : ApiController
{
    public IEnumerable Get()
    {
         var result = new List
         {
             new CompanyReport{Year = "2008&", Sales = 1000, Expense = 452},
             new CompanyReport{Year = "2009", Sales = 1150, Expense = 652},
             new CompanyReport{Year = "2010", Sales = 950, Expense = 1052},
             new CompanyReport{Year = "2011", Sales = 1150, Expense = 252},
         };

         return result;
     }
 }

Api Controller sınıfımız olan CompanyController sınıfının Get() metodu CompanyReport verilerini içeren JSON tipinde bir veri seti döndürmektedir. Google Chart API aynı şekilde grafik çizim verilerini JSON tipinde almaktadır. Bu sayede en başa dönecek olursak, iki ayrık sistemi JSON ortak noktasında buluşturmuş olacağız.

Grafik çizim işlemini View tarafında bir Script içerisinde gerçekleştirmeye çalışalım. Scrip içerisine referans olan Google Char ve JQuery Javascript dosyalarını Google CDN üzerinden çağırmaktayım.

<script src="https://www.google.com/jsapi" type="text/javascript">// <![CDATA[
  <script type='text/javascript'
          src='https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js'/>
  <script type="text/javascript">

        function drawChart() {
           $.getJSON(&quot;/api/Company&quot;, null, function (items) {
               var table = new google.visualization.DataTable();
               table.addColumn('string', 'Yıllar');
               table.addColumn('number', 'Satışlar');
               table.addColumn('number', 'Giderler');

               for (var i = 0; i < items.length; i++) {
                     table.addRow([items[i].Year, items[i].Sales,items[i].Expense]);
               }

               var options = { title: 'Şirket Raporları' };
               var chart = new google.visualization.ColumnChart(
                                document.getElementById('chart_div'));
               chart.draw(table, options);
           });
        }
  google.load(&quot;visualization&quot;, &quot;1&quot;, { packages: [&quot;corechart&quot;] });
  google.setOnLoadCallback(drawChart);
// ]]></script>

Artık uygulamamızı çalıştırdığımızda Api verileriyle Google grafikleri çizilmiş olacaktır.

Bir sonraki yazıda görüşmek dileğiyle.

Kaynak Kod: Burada

Asp.Net MVC Web API Projesinde Ninject ile Dependency Injection

5 Tem

Bir önceki yazılarımdan biri olan MVC Projesinde Dependency Injection başlıklı yazıda MVC uygulamasında Controller sınıfı içerisine dışarıdan bağımlılıkların enjekte edilmesini incelemeye çalışmıştık. Bu yazımızda ise Asp.Net MVC Web Api uygulaması üzerinde Dependency Injection işlemini uygulamaya çalışacağız.

MVC uygulamasında Controller sınıfları System.Web.Mvc.Controller tipinden türetilirken API Controller sınıfları System.Web.Http.ApiController tipinden türetilmiştir. Bu nedenle Web API üzerinde Dependency Injection uygularken bir önceki örnek uygulamadaki yöntemden daha farklı bir yöntem kullanacağız.

public class ValuesController : ApiController
{
     readonly IProductRepository productRepository;
     public ValuesController(IProductRepository productRepository)
     {
          this.productRepository = productRepository;
     }

     public IEnumerable<string> Get()
     {
         return productRepository.GetValues();
     }
}

API içerisine bağımlılıkları enjekte ederken IProductRepository interface tipini uygulayan(implemente eden) sınıfları göndermeye dikkat edeceğiz.

WEB API içerisinde Dependency Injection işlemini gerçekleştirmek için yine MVC’de olduğu gibi IoC container kütüphanelerinden faydalanmamız gerekiyor.

WEB API projelerinde Controller sınıflarının parametreli şekilde çalışabilmesi için bazı ayarlamaları yapmamız gerekecek. Bu ayarlamalardan biri, System.Web.Http alanında bulunan GlobalConfiguration statik sınıfındaki DependencyResolver özelliğinin düzenlenmesi olacaktır. Bu sayede WEB API, resolver mekanizmasını tanıyacaktır. Bu ayarlama Global.asax.cs dosyası içerisinde yapılmaktadır. Tanımlama:

public class WebApiApplication : HttpApplication
{
     protected void Application_Start()
     {
         // Diğer kodlar...
         GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(CreateKernel());
     }

     private IKernel CreateKernel()
     {
         IKernel kernel = new StandardKernel();

         kernel.Bind<IProductRepository>().To<ProductRepository>();

         return kernel;
     }

}

NinjectDependencyResolver adında bir sınıf hazırlıyoruz ve yukarıdaki gibi DependencyResolver özelliğine atıyoruz. DependencyResolver özelliği IDependencyResolver tipindedir. Bu sebeple NinjectDependencyResolver sınıfı da IDependencyReolver tipini uygulamalıdır.

public class NinjectDependencyResolver : NinjectDependencyScope, IDependencyResolver
{
      private readonly IKernel kernel;

      public NinjectDependencyResolver(IKernel kernel): base(kernel)
      {
          this.kernel = kernel;
      }

      public IDependencyScope BeginScope()
      {
          return new NinjectDependencyScope(kernel.BeginBlock());
      }
}

NinjectDependencyResolver sınıfını aynı zamanda NinjectDependencyScope sınıfından türetiyoruz. Bunun sebebi ise IDependencyResolver interface tipinin barındırdığı BeginScope() metodudur. Bu metodun bir şekilde doldurulması gerekmektedir. NinjectDependencyScope tipi de kendi oluşturmuş olduğumuz bir sınıf olacaktır. Bu sınıfı de şu şekilde oluşturabiliriz.

public class NinjectDependencyScope : IDependencyScope
{
    IResolutionRoot resolver;

    public NinjectDependencyScope( IResolutionRoot resolver)
    {
        this.resolver = resolver;
    }

     public void Dispose()
     {
        IDisposable disposable = resolver as IDisposable;

        if (disposable!=null)
        {
            disposable.Dispose();
        }

        resolver = null;
     }

     public object GetService(Type serviceType)
     {
         if (resolver==null)
         {
             throw new ObjectDisposedException("this", "This scope has been disposed");
         }

         return resolver.TryGet(serviceType);
     }

     public IEnumerable<object> GetServices(Type serviceType)
     {
         if (resolver == null)
         {

              throw new ObjectDisposedException("this", "This scope has been disposed");
         }

         return resolver.GetAll(serviceType);
     }

}

Son aşamayı da bu şekilde tamamladıktan sonra projemiz çalışabilir hale gelmiş demektir.

WEB API Sonuç
WEB API Sonuç

Projenin örnek kodlarını SkyDrive üzerinden paylaşıyorum.

Kaynak Kod: Burada

ASP.NET MVC Projesinde Dependency Injection Uygulanması

30 Haz

Daha önce hazırladığım Dependency Injection Tasarım Deseni başlıklı yazıda, yazılım tasarımında sınıfların birbirine olan bağımlılıklarını esnetmeyi ve bağımlılıkların sınıf dışından enjekte edilmesini incelemiştik. Bu yazımızda ise konunun bir örnek uygulaması niteliğinde olan ASP.NET MVC uygulamalarında Dependency Injection uygulamasını inceleyeceğiz.

Bu yazımızdaki örnek uygulamamızı geliştirirken, soyut sınıflar ile somut sınıflar arasındaki bağlantıyı kurarken ve somut nesne oluştururken IoC Container denen yardımcı kütüphanelerden faydalanacağız. Yine bu örnek uygulamada IoC Container kütüphanesi ile  somut nesnelerin kullanıcı(client) sınıf içerisinde “new” anahtar sözcüğü ile oluşturmak yerine, IoC Container tarafından oluşturulduğunu göreceğiz.

Örnek Uygulama

Örnek uygulamamızda ASP.NET MVC controller sınıfına Dependency Injection tarasım deseni ile bağımlılıkları dışarıdan soyut nesneler(interface veya abstract) yardımıyla vererek uygulamayı çalıştırmayı deneyeceğiz.

Öncelikle Controller sınıfımızı tanımlayarak işe başlayabiliriz.

public class HomeController : Controller
{
    private readonly IProductService productService;

    public HomeController(IProductService productService)
    {
        this.productService = productService;
    }
    public JsonResult Index()
    {
        IEnumerable<Product> products = productService.GetBestSellers();

        return Json(products, JsonRequestBehavior.AllowGet);
    }

}

Gördüğünüz üzere, Controller sınıfında hiç bir şekilde nesne oluşturma işlemi gerçekleştirilmiyor. Dışarıda oluşturulan ProductService nesneleri Controller sınıfı içerisine enjekte ediliyor. IProductService tipi bir interface’dir. Bu interface tipini uygulayan sınıflar HomeController içerisinde çalışabilir. IProductController tipindeki nesneler constructor metodu yardımıyla sınıf içerisine alınıyor.

ASP.NET MVC Controller sınıflarının varsayılan(default) halleri çalışma zamanında parametresiz constructor metodlarını ararlar. Bu tanımlama ASP.NET DefaultControllerFactory içerisinde belirlenmiştir. ASP.NET MVC open source olduğundan isteyen MVC kodlarını açıp inceleyebilir. Biz constructor seviyesinde injection işlemi yapacağımızdan DefaultControllerFactory sınıfının GetControllerInstence metodunu ezerek yani yeniden tanımlayarak istediğimiz formata getirmeliyiz.

Bu tanımlamayı yapmadan önce uygulamada kullanacağımız NInject kütüphanesinden bir iki cümle ile bahsedelim. Ninject kitüphanesi bir konteynır olarak çalışır. Soyut nesneler ile somut nesnelerin eşleştirildiği ve istendiğinde somut nesnelerin(new) oluşturulduğu kütüphanelerdir.

public class NinjectControllerFactory : DefaultControllerFactory
{
     private readonly IKernel kernel;

     public NinjectControllerFactory()
     {
         kernel = new StandardKernel(new NinjectBindingModule());
     }

     protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
     {
         return controllerType == null ? null : (IController)kernel.Get(controllerType);
     }
}

public class NinjectBindingModule : NinjectModule
{
     public override void Load()
     {
         Kernel.Bind<IProductService>().To<ProductService>();
     }
}

Burada tanımlanan kod parçasında anlatılmak istenen şey DefaultControllerFactory metodunun Controller Instance oluştururken karşılaşacağı parametresiz constructor metodu oluşturma hatasını engellemektir. Ninject aracılığı ile Controller tipine göre bir nesne oluşturuyor. Örneğin HomeController için controllerType HomeController olacaktır ve constructor metodunda IProductService interface tipini parametre olarak alacaktır. HomeController tipinde bir nesne oluştururken constructor metodda karşılaştığı parametreyi Kernel bildiği için hemen nesnesini oluşturarak Controller sınıfına vermektedir.

Artık Global.asax sınıfı içerisine bu yapıyı tanıtma işlemi kaldı. Onu da şu şeklide gerçekleştirebiliriz.

public class MvcApplication : System.Web.HttpApplication
{
     protected void Application_Start()
     {
        //diğer tanımlamalar...

        ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
     }
}

Uygulamayı çalıştırdığımızda çıktı olarak şu şekilde bir JSON veri dönecek:

[{"Name":"Notebook"},{"Name":"PC"}]

Örnek uygulamanın kodlarını SkyDrive üzerinden paylaştım. Bir sonraki yazıda görüşmek üzere.

Kaynak Kodlar: Burada

Asp.Net XMLHttpRequest ve Proxy Uygulaması

20 Haz

Bir önceki yazımızda XMLHttpRequest nedir, nasıl kullanılır ve kullanılırken ne gibi sorunlar ile karşılaşılır şeklinde bir incelemede bulunmuştuk.

Bu yazıda ise ASP.NET MVC tabanlı bir uygulamada javascript ile XMLHttpRequest göndermeyi ve karşılaşılan sorunları inceleyeceğiz.

Bir önceki yazımızda, bir XMLHttpRequest gönderme işleminin uygulama sunucusuna yapılması durumunda bir sorunla karşılaşmayacağımızdan ancak dışarıdaki bir sunucuya istek gönderirken bir yetki sorunuyla karşılaşacağımızdan bahsetmiştik.

Şimdi ASP.NET MVC uygulamasında bulunan bir controller sınıfındaki JsonResult döndüren bir action metoduna XMLHttpRequest göndermeye çalışalım.

public class HomeController : Controller
{
     public JsonResult Application()
     {
         var jsonResult = new {
                                Name = "XMLHttpRequest Applcaition",
                                Date = DateTime.Now.AddDays(-5).ToShortDateString()
                              };

        return Json(jsonResult, JsonRequestBehavior.AllowGet);
      }
}

Basit bir JSON nesnesi döndüren bir metod olşuturduk. Şimdi View tarafından bu metoda bir XMLHttpRequest gönderelim. Yani kendi uygulamamızı sunan sunucuya bir XMLHttpRequest gönderelim ve internet tarayıcımızın tavrına bakalım.

Uygulama Sunucusuna Gönderilen XMLHttpRequest
Uygulama Sunucusuna Gönderilen XMLHttpRequest

İnternet tarayıcımız hiç itiraz etmeden sorguyu Javascript aracılığı ile başarılı bir şekilde almıştır.

Şimdi de uygulama sunucumuzun dışındaki bir sunucuya istek(request) göndermeye çalışalım ve sonucu görelim.

Farklı Sunucuya XMLHttpRequest gönderilmesi
Farklı Sunucuya XMLHttpRequest gönderilmesi

Tarayıcımız kodu derlerken bize bir itirazda bulundu. Hata “Erişim Engellendi” şeklinde. İnternet tarayıcımız bize uygulama sunucumuz dışına çapraz(cross) sorgu gönderme izni vermiyor ve ağ iletişimini kapatıyor.

Bu sorunu aşmak için uygulama sunucumuza bir istek gönderip, uygulama sunucumuz üzerinden ilgili sorgunun sonucunu almaya çalışacağız. Yani arka kapıdan dolaşmak zorunda kaldık.

Şimdi projemize bir Proxy uygulaması oluşturup bu uygulama üzerinde işlemi deneyelim. Projemize Proxy adında bir dizin açıp içerisine Proxy.ashx adında bir Generic Handler ekleyelim.

public class proxy : IHttpHandler
{
     public void ProcessRequest(HttpContext context)
     {
         context.Response.ContentType = "text/plain";

         WebRequest request = WebRequest.Create("http://www.google.com");
         WebResponse webResponse = request.GetResponse();

         Stream responseStream = webResponse.GetResponseStream();

         if (responseStream != null)
         {
              StreamReader reader = new StreamReader(responseStream);

              context.Response.Write(reader.ReadToEnd());
         }
     }

     public bool IsReusable
     {
        get
        {
             return false;
        }
     }

}

Javascript üzerinden bu proxy’ye XMLHttpRequest göndereceğiz ve proxy’nin elde ettiği sonucu kullanacağız.

Proxy ile XMLHttpRequest
Proxy ile XMLHttpRequest

Olay bu kadar basit aslında. Bu şekilde istediğimiz sosyal paylaşım sitelerine, değişik hizmetler sunan web servislerine Javascript üzerinden erişebiliriz.

Bu yöntem, CBS tarzı harita uygulamalarında farklı yerlerde barınan sunuculara Javascript API’ler üzerinden sorgu gönderirken çok işe yarıyor. Örneğin Map servislerini bir sunucudan, Harita resimlerini başka bir sunucudan, kişi bilgilerini ayrı bir servis üzerinden çekip tek bir sunum ortamında faydalanmak mümkün hale gelebiliyor. Farklı çözümlerde bu yöntemi kullanmak size kalmış.

Bir sonraki yazıda görüşmek dileğiyle.

XMLHttpRequest için Proxy Kullanımı

13 Haz

Günümüzde değişik web hizmetlerini(service) kullanıcılara açan internet uygulamaları arttıkça, haliyle bu sunulan hizmetleri alabilmek adına değişik yöntemler kullanılır. Örneğin sosyal ağların sunduğu servisler, hava durumu, haber veya blog servisleri tarafından sunulan bilgileri biz de alıp uygulamalarımızda kullanmak isteriz.

AJAX(Asynchronous Javascript and XML) tabanlı web uygulamaları yaygınlaştıkça, web sunucularına istek gönderip, sunucu tarafında yeniden oluşturulan HTML çıktılarını almak yerine var olan sayfaları hiç yenilemeden(refresh) sorgu gönderip cevabı mevcut sayfa üzerine dökme yoluna gidiliyor. İnternet tarayıcıları (web browser) üzerinden Javascript kodu ile sunuculara istek gönderip cevap almak mümkündür. Bu gibi istekleri(request) karşılamak üzere tarayıcılar tarafında bulunan XMLHttpRequest nesnesi devreye girmektedir.

XMLHttpRequest nesnesi ile uygulamamızın bulunduğu sunucu dışında bir sunucuya istek göndermek güvenlik açısından bazı kısıtlamalara takılmaktadır. Bu gibi sorunları aşmak için direk başka sunucuya (örneğin Yahoo servisine)istek göndermek yerine kendi sunucumuza bir proxy uygulaması oluşturup bu proxy üzerinden istekleri göndermek uygun olacaktır.

Neden Proxy Kullanılır?

Modern Web tarayıcıları, sunduğu geliştirici ve kullanıcı dostu eklentilerin yanı sıra güvenliği sağlamak açısından başarılıdırlar. XMLHttpRequest çağrıları içeren bağlantılarda web tarayıcılar bir güvenlik sınırlaması getirirler. Bu sınırlama ile bir script veya uygulamanın kendi geldiği sunucu haricinde bir sunucuya istek göndermesi engellenir. Aşağıdaki resimde web tarayıcı üzerinden, uygulamanın kendi web sunucusuna HTTP metodlarıyla(GET, POST, v.s) veya XMLHttpRequest ile istek göndermesinin mümkün olduğu gösterilmiştir.

XMLHttpRequest isteği
XMLHttpRequest isteği

Ancak yazdığınız bir script ile web tarayıcısı üzerinden başka bir sunucuya istek gönderecek olursanız (örneğin Yahoo web servislerine), tarayıcı aradaki bağlantıyı engeller. Aşağıdaki resimde bu durum gösterilmiştir.

XMLHttpRequest dış sunucu isteği
XMLHttpRequest dış sunucu isteği

Bu gibi durumlarda genellikle kullanılan çözüm, proxy kullanılmasıdır. Bir web servisine internet tarayıcısı üzerinden direk istek göndermek yerinde, kendi sunucunuzda bulunan bir proxy’ye isteği gönderirsiniz. Proxy, aldığı isteği ilgili web servisine göndererek aldığı cevabı internet tarayıcınızdaki client tabanlı uygulamanıza gönderir. Servis ile bağlantıyı kuran web sunucusu olduğundan internet tarayıcısı açısından artık bir sorun kalmamıştır.

XMLHttpRequest Proxy Kullanımı
XMLHttpRequest Proxy Kullanımı

Client tabanlı web uygulamaları olarak Javascript, Java Flex, Silverlight gibi uygulamaları düşünebilirsiniz. Bu tarz uygulamalar web tarayıcıları üzerinden çalışırlar. Web tarayıcılar üzerinden çalışan uygulamalardan Yahoo, Twitter gibi sitelere ait servislere ulaşmak için proxy kullanabilirsiniz.

Kaynak: http://developer.yahoo.com/javascript/howto-proxy.html

Javascript Nesne Kavramı

11 Haz

Javascript dünyası her ne kadar client taraflı uygulamalar için geliştirilmiş bir dil olsa da kullanıcılara nesnelerin tanımlanabildiği ve kullanılabildiği bir ortam sunmaktadır. Javscript içerisinde tanımlı kendine ait bazı nesneleri şu şeklide sıralayabiliriz. String, Date, Math, JSON v.b. Bu nesnelerin yanında kendimiz de nesneler tanımlayıp kullanabiliriz.

Javascript Nesne Oluşturulması

Javascript, standart olarak Object adında bir nesne sunar. Oluşturulan nesneler de Object türündedir. Örneğin bir nesnenin oluşturulmasını şu şekilde yapabiliriz.

       var bankAccount = new Object();

Bu şekilde herhangi bir üyesi bulunmayan ve sadece “Object” tipine ait üyeleri barındıran bir bankAccount nesnesi oluşturmuş olduk. Bu nesneyi daha basit bir şekilde aşağıdaki gibi tanımlayabiliriz.

       var bankAccount = {};

Yani Object anahtar kelimesini kullanmadan da tanımlama yapmak mümkündür.

Nesnelere Property eklenmesi

Oluşturduğumuz nesnelere property eklenmesi işlemini aşağıdaki şeklide gerçekleştirebiliriz.

       var bankAccount = {};
       bankAccount.number = 114521;

nesnelere bir değer veya fonksiyonu property olarak belirleyebiliriz. Bir property eğer bir fonksiyonu işaret ediyorsa ona metod diyebiliriz.

       var bankAccount = {};
           bankAccount.number = 114521;
           bankAccount.owner = "Bayram Üçüncü";
           bankAccount.balance = 500;
           bankAccount.details = function () {
             return "Account: " + this.number +
                    " belongs to " + this.owner +
                    "\nBalance: " + this.balance;
      };

Yukarıda tanımladığımız bankAccount nesnesine ait “details” isimli property bir metoddur. Metodlar içerisinde kullanılan this anahtar kelimesi metodun ait olduğu nesneyi ifade eder. Bu sebeple yukaridaki “details” metodu içerisinden diğer üyelere this anahtar kelimesi ile ulaşabilmekteyiz. Metod içerisinden this anahtar kelimesini kullanmadan bir üyeye erişmeye çalışırsak hata ile karşılaşırız.

Nesne Üyelerinin Oluşturma Sırasında Eklenmesi

Nesneleri oluşturduktan sonra üyelerin belirlenmesi mümkün olduğu gibi, nesne oluşturulurken üyelerinin belirlenmesi de mümkündür. Kodun temiz olması açısından kullanılabilecek bir gösterim olarak değerlendirilebilir.

       var bankAccount = {
           number: 114521,
           owner: "Bayram Üçüncü",
           balance: 500,
           details: function () {
                    return "Account: " + this.number +
                           " belongs to " + this.owner +
                           "\nBalance: " + this.balance;
           }
       };

Constructor(kurucu metod) Kullanılması

Yukarıda tanımladığımız nesne oluşturma şeklini tekrar hatırlayalım. Basit haliyle bir nesnenin oluşturulması şu şekildeydi.

       var bankAccount = {};

Bu nesneye bir constructor eklemek istediğimizde ne yapmamız gereken şudur:

       var bankAccount = function (number, owner, balance){};

Bu fonksiyon “{}” parantezlerden hemen önce belirlenmiştir. Javascript ortamında construstor fonksiyonlar property’leri this isimli nesneye atarlar. Javascript ortamındaki constructor fonksiyonlar C# veya Java’daki sınıflara benzerler. Constructor kullanarak yeni bir nesne oluşturup o nesneye

       var BankAccount = function (number, owner, balance){
           this.number = number,
           this.owner = owner,
           this.balance = balance,
           this.details = function() {
             return "Account: " + this.number +
                    " belongs to " + this.owner +
                    "\nBalance: " + this.balance;
           };
        };

Oluşturduğumuz bu nesneyi şu şeklide kullanabiliriz.

       var myAccount = new BankAccount(914521, "Bayram Üçüncü", 500);

Constructor fonksiyonu tanımladıktan sonra nesne örneğinizi oluşturmak için “new” operatörünü kullanabilirsiniz. Oluşturduğunuz bu nesne örneğinin property’lerine ulaşabilirsiniz.

Nesnelerin Prototiplerinin Kullanılması

Javascript Object tipinde bulunan prototype adlı özel bir metod, tüm nesnelerde bulunur. Bu metod sayesinde nesnelere yeni property veya metodlar ekleyebilirsiniz. Constructor fonksiyonları ile kendi özel tiplerimizi oluşturmamız mümkündür. Oluşturduğumuz tipe ait iki farklı nesne örneği oluşturacağımız vakit her bir nesne örneği kendi property kümesini bünyesinde barındırır. Bu durum, veri tutucu property’ler için makul görünse de metodlar için bir sorun haline gelebilir. Metodlarımızı oluşturduğumuz tip içerisinden ayırabiliriz.

Örnek-1: Prototype kullanılmadan

       var Rectagle = function (x,y) {
           this.x = x;
           this.y = y;
           this.Area = function() { return x*y; };
      };

Örnek-2: Prototype kullanarak

       var Rectangle = function (x, y) {
           this.x = x;
           this.y = y;
       };

       Rectangle.prototype = {
           Area: function() { return (this.x * this.y); }
       };

Örnek-2 de alan hesaplayıcı metod olan Area metodu Örnek-2 de tipin prototype metoduna tanımlanmıştır.

Bu bize ne fayda sağlamıştır? Örnek-1 de constructor içinde tanımlanan fonksiyon için her Rectangle nesnesi oluşturulduğunda bellekte anonim bir fonksiyon oluşturulacak ve yer tutacak. Ancak Örnek-2 de durum farklı olacaktır. Prototype property’ler static olduklarından her Rectangle nesnesi prototype içine tanımlanan metodları referans olarak görecektir.

Ayrıca Rectange tipine ait değer tutucu (x,y) üyeler ve fonksiyonlar ayrılmış oldu. Bu ayrımı farklı Javascript dosyalarına bile dağıtmak mümkündür.

Prototype kullanımı öncelikli olarak performans artışı sağlamakla birlikte kodun okunabilirliğini de arttırmak açısından faydalı olmaktadır.

Bu yazımızda Javascript ile nesnelerin oluşturulmasını, constructor kavramını, nesnelere property eklenmesini ve Object tipinin bünyesindeki prototype kullanımını incelemiş olduk. Bir sonraki yazıda görüşmek üzere.