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.

Javascript Kod Kapsamının Yapılandırılması

10 Haz

Web uygulamalarımız geliştikçe ve yazılan kod satırları arttıkça, kodun yönetimini kolaylaştırmak amacıyla kodun iyi yapılandırılmış olması önem kazanmaya başlar. Bu kural, yazılımcılar tarafından edinilen tecrübelerle ortaya konmuştur.

Bu yazımızda Javascript kodunun iyi yapılandırılmasıyla ilgili kurallardan bahsedeceğiz. Javascript ortamında değişkenler için kod kapsamını incelemeye çalışacağız.

Değişkenlerin Erişilebilirlik Alanları

Javascript, internet tarayıcılar tarafından yorumlanan bir dildir. Bu sebeple Client taraflı uygulamalar Javascript ile geliştirilebilir. Diğer popüler dillerden(C++, C#, Java v.b) bu yönüyle ayrılır. Kod yazım kuralları diğer programlama dillerine biraz benzerdir.

Javascript ortamında tanımlanan değişkenlere nereden ulaşılabileceğine geliştiriciler karar verir. Bir değişken, her yerden ulaşılacaksa global şekilde tanımlanabilir veya sadece bir fonksiyon içerisinde kullanılacaksa yerel bir şekilde de tanımlanabilir.

Yani iki yeni kuralımız ortaya çıkmış oldu.

  • Değişkenler bir fonksiyonun dışında tanımlanmışsa global olur.
  • Bir fonksiyon içerisinde tanımlanmışsa yerel olur ve o fonksiyon içinde her yerden(fonksiyon içindeki başka bir fonksiyondan bile) erişilebilir.

Örnek-1:

<script type="text/javascript">
     var name = "Bayram";

     function getUsername() {
          alert(name);
     }
</script>

Bu örnekte “name” değişkeni global olarak tanımlanmıştır. “name” değişkenine artık her yerden erişilebilir. Bu kodu bir *.js dosyasına tanımlayıp dosyayı gören her yerden “name” değişkenine erişebiliriz.

Örnek-2:

<script type="text/javascript">

    var name = "Bayram";

    function getUsername() {
       var name = "Undefined";
       alert(name);
    }
</script>

Bu örnekte tanımladığımız “getUsername” fonksiyonu çalıştırıldığında çıktı olarak “Undefined” şeklinde bir uyarı penceresi açılacaktır. “Bayram” diye uyarı vermeyecektir. getUsername fonksiyonu içinde yerel olarak tanımlanan “name” değişkeni global tanımlanan “name” değişkenini dikkate almamıştır.

Bu gibi durumlar, bazen istemediğimiz sonuçlara yol açabilir. Örneğin bir değişkenin unutularak tekrar değiştirilmesi sonucu yanlış bilgi alınması veya verilmesi gibi durumlar yaşanabilir. Çünkü global olarak tanımlanan değişkenlere web uygulamanızın her yerinden ulaşabilirsiniz.

Bu gibi çakışma sorunlarını bertaraf etmek için Javascript tarafında faydalanabileceğimiz birkaç yöntem mevcuttur. Bunlar:

  • Hemen cevap veren fonksiyonlar
  • Namespace (Ad alanları)

Hemen Cevap Veren Fonksiyonlar

Hemen cevap veren fonksiyonlar, tanımlandığı anda çalışan fonksiyonlardır. Yani bir yerde tanımlayıp başka yerde çalışan fonksiyonlar gibi değillerdir. Hemen cevap veren fonksiyonları anonim fonksiyon gibi iki parantez içine sarmalayarak hemen çalışır hale getirebiliriz.

Örnek:

<script type="text/javascript">

    (function () {
         var firstName = "Bayram";
         var lastName = "Üçüncü";
         var fullName = firstName + " " + lastName;
    })();

</script>

Tarayıcı bu fonksiyonu gördüğü anda çalıştırır. Fonksiyon içinde tanımlanan değişkenler global ad alanını (namespace) boşuna kirletmemiş olur. Mesela “firstName” değişkenine bu fonksiyon dışından erişmek mümkün değildir.

Namespace (Ad Alanlarının Kullanımı)

Global değişkenlerin çakışmalarını gidermek için kullanılan bir diğer yöntem ise namespace kullanımıdır. Javascript ortamında namespece içerisine değişkenler ve fonksiyonlar tanımlamak mümkündür.

Örnek:

<script type="text/javascript">

     var MyGlobalMapNamespace = {

          getMapName: function () {
                return "Nokia Maps";
          },
          getMapExtent: function () {
                return "411124, 552442, 4253211, 4011225";
          },
          gtMapLayers: function () {
                return 4;
          },
          owner: "Bayram Üçüncü"
     }
</script>

Bu örnekte tanımladığımız MyGlobalMapNamespace namespace içindeki üyelere şu şeklide erişmek mümkündür:

       MyGlobalMapNamespace.getMapExtent();
       MyGlobalMapNamespace.owner="Bayram";

Namespace içerisinde tanımlı üyelere bir gizlilik veya kapsülleme(encapsulation) yapmak söz konusu değildir. Namespace adı ile içerisindeki üyelere dışarıdan erişim mümkündür.

Bu şekilde Javascript ortamında değişkenlerle ilgili erişim bölgelerini yani kod kapsamına giren ve girmeyen bölgeleri incelemeye çalıştık. Global ve Yerel değişkenlerin hangi kapsamlarda kaldığını, değişken çakışmalarında alınacak önlemleri inceledik. Bir sonraki yazıda görüşmek dileğiyle.

ArcGIS Server Sitesi Yapısı Verisyon 10.1

5 Haz

Günümüzde son kullanıcı ürünleri ucuzlamaya başladıkça sunucu taraflı uygulamalar ve teknolojilerin fiyatları artmaya başladı. Sunucu gelişiminin son noktası bulut teknolojisi oldu. Bulut teknolojisinin iyice yaygınlaşmaya başladığı günümüzde firmalar sunucu mimarilerini bu gelişime uydurmak adına adımlar atılmaya başlandı. Artık sunucu tarafında çalışan sistemleri durdurmadan donanımsal tak çıkar işlemleri yapmak yani donanımların yetmediği noktalarda ölçekleme yapmak çok kolaylaştı. ArcGIS tarafı da bu gelişim karşısında duyarsız kalmayarak mimarisinde bazı değişikliklere gitti.

Bu yazımızda ArcGIS Server 10.1 ile birlikte SOM-SOC modeli yerine gelen Site yapısının iç yüzünü inceleyeceğiz. ArcGIS Server Site yapısı, birden fazla bilgisayar üzerine konuşlandırılabilecek şekilde ayarlanabilen bileşenlerden oluşur. Sitedeki her bir bileşen kaynak yönetiminde belirli bir role sahiptir.

ArcGIS Server sitesi bileşenleri şu şekilde özetlenebilir:

  • Web sunucusu: Web uygulamalarını barındırır, isteğe bağlı güvenlik seçenekleri sunar ve ArcGIS Server için yük dengeleme işlemlerini gerçekleştirir.
  • Web Adaptör: Gelen istekleri farklı CBS sunucu(GIS Server) bilgisayarlarına ileterek ArcGIS Server ile kurumsal web sunucunuzu bütünleştirir.
  • GIS Server(CBS sunucusu): CBS web hizmetleri için gelen istekleri karşılamak için çalışır. Bir CBS sunucusu harita çizimleri, görüntü hizmetleri, veritabanı senkronizasyonu, veri arama gibi birçok işlemi gerçekleştirir.
ArcGIS Server Site Mimarisi
ArcGIS Server Site Mimarisi

Bu resimde özetle ArcGIS Server sitesinin her bir bileşenin görevi ve bağlı olduğu bileşen gösterilmiştir.

Web Sunucusu (Server)

Web sunucusu web uygulamalarını barındırır, isteğe bağlı güvenlik seçenekleri sunar ve ArcGIS Server için yük dengeleme işlemlerini gerçekleştirir. ArcGIS  Server, IIS, WebSphere ve WebLogic gibi birçok web sunucusuyla uyumlu çalışır.

GIS server (CBS sunucusu) bileşeni servislerinizi HTTP protokolü üzerinden IIS gibi ayrı bir işlem gerektirmeden dışarı açabilir. Eğer web sunucusunun yerel güvenlik yapılandırmalarından(örneğin kullanıcı doğrulamasından)  faydalanmak isterseniz veya web uygulamalarınızı barındırmak isterseniz dağıtımınıza bir web sunucusu dahil edebilirsiniz.

Web Adaptor(Adaptör)

ArcGIS Web Adaptor, temelde web sunucunuzdan gelen istekleri CBS sunucularına(GIS Server) ileten bir web uygulamasıdır. Web Adaptörler siteye hangi bilgisayarların eklenip hangilerinin çıkarıldığını izler ve gelen trafiği bu bilgisayarlara uygun olarak dağıtır. Web Adaptör kullanarak siteniz için isimlendirme ve bağlantı(port) noktalarını yönetebilirsiniz. Örneğin varsayılan port 6080 ve site ismi “arcgis” iken Web Adaptör ile bunları değiştirebilirsiniz. Web Adaptörü sayesinde güvenlik için web sunucusunun yerel imkanlarını kullanabilir, ArcGIS Manager için veya ArcGIS Server yönetim dizinleri için dışarıdan gelen istekleri engelleyebilirsiniz.

Çalışma prensibi olarak bir servis isteği geldiğinde Web Adaptörü bu isteği GIS Server bilgisayarlarına iletir. Daha sonra GIS Server bilgisayarları, hangi bilgisayarın kullanılabilir olduğunu ve hangi bilgisayara işin atanacağı belirlemek için birbirleri ile iletişime geçerler. Eğer Web Adaptörü, GIS Server tarafının erişilemez durumda olduğunu belirlerse o sunucuya istek göndermeyi durdurur.

Web Adaptörü sitenizi sadece web ağ geçidi veya giriş noktası yapılandırmak için tek yöntem değildir. Diğer ağ geçidi teknolojileri de kullanılabilir. Fiziksel HTTP yük dengeleyiciler, ağ yönlendirici cihazları veya üçüncü parti bir yazılımla da bu işlemleri gerçekleştirmek mümkündür.

GIS Server (CBS sunucusu)

Sitenizde ArcGIS Server için kurulan bilgisayarları CBS sunucusu olarak düşünebilirsiniz. Haritalar, adresler, koordinatlar, coğrafi işlemler gibi web hizmetler için gelen istekler site içindeki ulaşılabilir durumdaki CBS sunucu bilgisayarına atanır. Daha sonra CBS sunucusu gelen isteğe uygun hizmeti hazırlayarak kullanıcıya cevap olarak gönderir. Aslında CBS sunucuları sitenizin iş merkezidir.

CBS sunucuları servisleri HTTP protokolü üzerinden dışarı sunarlar.

Birden fazla CBS sunucusu kullanarak sunuculardan birinin kesintiye uğradığı kriz durumlarında sitenizi kesintilere karşı koruyabilirsiniz. Bir CBS sunucusu devre dışı kaldığı durumda Web Adaptörü, gelen istekleri sitenizdeki diğer CBS sunucularına dağıtır. Bunlara ek olarak CBS sunucuları diğer CBS sunucularının eklenip çıkarıldığını algılayabilir. Böylece bulut teknolojisi gibi aygıt takılıp çıkarılabilen ortamlarda iyi çalışır.

Clients (Kullanıcılar)

ArcGIS Server sitesi kullanıcılarını şu şekilde isimlendirebiliriz.

  • Web Tarayıcılar: ArcGIS Server sitesi bünyesindeki servislere web tarayıcılar aracılığıyla ulaşmak mümkündür.
  • Mobile Aygıtlar: Akıllı telefonlar ve tabletler gibi taşınabilir aygıtlar ile web uygulamalarına ve web servislerine ulaşılabilir. Harita görüntüleme, yer bulma gibi uygulamalara rahatlıkla erişilebilmektedir.
  • ArcGIS Exploerer: ArcGIS Explorer görsel ve navigasyon için hazırlanmış ücretsiz bir masaüstü uygulamasıdır. ArcGIS Server servislerinizi veri olarak ekleyip zengin içerikli görüntü elde edebilirsiniz.
  • ArcGIS Desktop: ArcGIS Desktop uygulaması hem ArcGIS Server servislerini tüketebilir hem de yönetim aracı olarak kullanabilir. Bazı araçlar sayesinde sunucuya yayınlar sunmanız mümkündür. Bazı desktop uygulamalarını ArcMap, ArcCatalog, ArcGlobe, and ArcReader olarak sıralayabiliriz. Catalog ile uygun URL adresi ile CBS sunucularına bağlanabilirsiniz.
  • ArcGIS Engine: ArcGIS Engine uygulamaları CBS sunucularından faydalanır. ArcGIS Engine  geliştirircileri yazdıkları uygulamalar aracılığıyla CBS sunucularına veri gönderebilirler.

Kaynak: http://resources.arcgis.com/en/help/main/10.1/index.html#//0154000003p4000000

ArcGIS Server 10.1 Server Yenilikleri

4 Haz

Bir önceki blog paylaşımında ArcGIS Server 10.0 mimarisinden bahsetmiştim. Bu paylaşımın amacı ArcGIS Server 10.0 mimarisi ile 10.1 mimarisi arasındaki farkları görebilmekti. Bundan sonraki paylaşımlar 10.1 üzerinden ve çıkarsa daha yeni versiyonlar üzerinden devam edecektir. Bu yazımızda 10.1 versiyonunun getirdiği yenilikler üzerinden ilerleyeceğiz.

ArcGIS Server 10.1 verisyonu 64 bit bir uygulama olarak çalışır. Böylece CBS hizmetleri için donanım özelliklerinden tam olarak yararlanılır. Bu değişiklik, ArcGIS sunucularının ölçeklenebilirliğini arttırmak için yapılmıştır. 64 bit donanımlar artık mevcut endüstriyel standart haline geldiği göz önüne bulundurularak 32 bit işletim sistemlere verilen destek durdurulmuştur.

ArcGIS Server 10.1 Kurulum Yenilikleri

ArcGIS Server kurulumu önemli ölçüde basitleştirilmiştir. Önceki sürümlerde kurulum sırasında izlenen birçok adım kaldırılmıştır. Yeni özellikleri şu şekilde sıralayabiliriz.

  • Artık .Net Framework veya Java Runtime gibi yüklemelere gerek kalmıyor.
  • Ayrı bir sunucu (Microsoft IIS, WebSpahare, v.b) ile entegrasyona gerek kalmıyor. Artık sunucu için ArcGIS kurulumu yaptığınızda, web yönetim araçları ve uygulamalarıyla servis tabanlı bir CBS sunucusu(GIS Server) karşımıza çıkıyor.
  • CBS kaynaklarınıza ulaşmak için kurulum sırasında sizden tek bir kullanıcı hesabı istenir. Bu hesaba ArcGIS Server hesabı denir. 10.1 sürümünde kurulum sonrası adımlar ve ayrı ayrı ayarlanan SOM, SOC ve ArcGIS web servis hesapları yoktur.
  • DCOM bağımlılığı yoktur.

Birden fazla bilgisayar üzerine dağıtılmış kurulum yapmak basitleştirilmiştir. Her bilgisayarda aynı kurulumu yapılır, daha sonra ArcGIS Server Manager üzerinden bağlantılar gerçekleştirilir.

Windows ve Linux Ayrımı

Önceki versiyonlarda Microsoft .Net Framework ve Java platromu için sunulan ArcGIS Server, artık 10.1 versiyonuyla işletim sistemi seviyesine çekilmiştir. Kurulumlar Microsoft için ArcGIS(Server)  ve Linux için ArcGIS(Server) şeklinde yapılmaktadır.

ArcGIS Server 64 bit

ArcGIS 10.1 versiyonu 64 bit uygulama olarak çıkmıştır ve 32 bit işletim sistemi desteği durdurulmuştur.

SOM ve SOC modeli artık ArcGIS Server sitesi

Önceki ArcGIS Server versiyonlarında CBS sunucusu(GIS Server) SOM(Server Object Manager) ve SOC(Server Object Container) şeklinde iki bileşenden oluşmaktaydı. SOC bileşenleri GIS servislerinde barıdırılmaktadır ve SOM bileşeni tarafından yönetilir ve kullanıcıların hizmetine sunulur.

ArcGIS Server 10.1 ile birlikte SOM-SOC modeli ArcGIS Server sitesi şeklinde değiştirilmiştir. Bir site, bir veya birden fazla makine(GIS Server) üzerine yapılmış dağıtımdır. 10.1 ile gelen site mimarisi SOM-SOC modelinden daha sağlamdır. Hata riskini azaltır, yeni makinelerin eklenmesini ve mevcutların yönetimini kolaylaştırır.

ArcGIS Web Adaptör

ArcGIS Web Adaptor, ArcGIS Sunucusunun kendi web sunucunuz ile çalışması için yapılan bir kurulumdur. ArcGIS Server dış dünyaya REST ve SOAP servisleri sunabilmektedir. Eğer siteniz için kendi özel URL adreslerinizi ayarlamak istiyorsanız veya web sunucunuzun güvenlik modeli ile entegrasyon sağlamak istiyorsanız ArcGIS Web Adaptor kurulumunu yapmalısınız. Bu bileşen, eğer birden fazla makine ile bir siteyi yapılandıracaksanız ve güvenliği sıkılaştırmak istiyorsanız önerilir.

Kaynak: http://resources.arcgis.com/en/help/install-guides/arcgis-server/10.1/index.html#/What_s_new_in_the_ArcGIS_10_1_for_Server_install/01nm0000000m000000/

ArcGIS Server 10.0 Dağıtılmış Sistem Mimarisi

3 Haz

ArcGIS Server, sunduğu hizmetleri birden çok makine üzerine dağıtarak ölçeklenebilir bir sistem mimarisi sunmaktadır. ArcGIS sunucusunu ilk kez kuruyorsanız büyük olasılıkla tüm bileşenlerini aynı makine üzerine kurarak test edeceksiniz. ArcGIS Server uygulamanızı farklı makinelere dağıtmak istiyorsanız dağıtılmış kurulum(distributed installation) yapmalısınız. Bu sayede sisteminize erişen kullanıcı sayısı için kabul edilebilir bir düzeyde bir performans elde edebilirsiniz.

ArcGIS Server için yapılan dağıtılmış kurulum sayesinde sistem bileşenleri aynı yerel ağda birden fazla makine üzerinde barındırılır. Aşağıdaki grafikte ArcGIS Server bileşenlerinden SOM(Server object manager), SOC(server object container) ve Web sunucusunun farklı makineler üzerinde dağıtıldığını görebiliriz. Bu yapı Arcgis Server 10.0 için hazırlanmıştır. Daha sonraki versiyonlarda değişiklikler olabilir.

ArcGIS Server Mimarisi
ArcGIS Server 10.0 Mimarisi

Dağıtılmış şeklide kurulmuş olan ArcGIS Server sistemine daha fazla makine ekleyerek dışarı sunulan hizmeti daha da iyileştirmek mümkün hale gelmektedir. CBS (GIS) işlemlerinde yük çekici işlemler(container processes) CPU kaynağını çok fazla tükettiğinden sisteme birden fazla SOC makinesi dahil etmek bu yükün paylaşılmasını ve sistemin iyileştirilmesini sağlamaktadır.

ArcGIS Server bileşenlerini farklı makineler üzerinde akıllıca dağıtmak donanım kaynaklarınızın en etkin şekilde kullanılmasını sağlar. Örneğin kullanabileceğiniz makine sayısı yeterli değilse Web sunucusunu ve SOM bileşenini aynı makine üzerinde barındırabilirsiniz. Çünkü SOM, diğer bileşenlere nispeten daha az bellek kullanır.  Kalan donanım kaynakları da CBS sunucusunun işleyebileceği yükü dengelemek için SOC makinelerine aktarılabilirsiniz.

Dağıtılmış ArcGIS Server kurulumu yapmak, ArcGIS Desktop veya ArcGIS Engine kurulumuna benzemez. Çünkü birbiri ile konuşan makineleri doğru şekilde yapılandırmalısınız. SOM makinesinin sistemdeki bir SOC makinesine istekte bulunabilmesi gerekmektedir. Her makine aynı veri kümesi ve dizini ile çalıştığından her makine ortak bir isimlendirme kuralı (UNC path) ile aynı kayna erişmelidir.

Güvenlik mekanizmaları bazen makineler arasında iletişim sorunu çıkarabilir. Örneğin SOC hesabı farklı makineler üzerinde okuma ve yazma izinleri gerektirebilir. Bu sebeple ArcGIS Server bileşenleri arasında açık bir şeklide iletişim kurmaları gerektiğinden bu bileşenler arasında güvenlik duvarına gerek yoktur. Örneğin SOM ve SOC arasında veya SOM ve Web sunucusu arasında güvenlik duvarı gerekmez.
Ayarların Yapılması
Dağıtılmış bir ArcGIS Server sisteminin hizmete sunulması için atılacak ilk adım yapılandırma tasarımıdır. SOM, SOC, Web Application Developer Framewrok (ADF) ve Web Service endpoint bileşenleri aynı makineye yüklenebilir veya birden fazla makine üzerine dağıtılabilir. ADF Runtime Web sunucusu gibi aynı makinede yüklü olmalıdır.

ArcGIS Server Manager sunucunuzu yönetmenize yardımcı olan ve basit web uygulamaları oluşturmanızı sağlayan isteğe bağlı bir bileşendir. Bu bileşen iki parçadan oluşmaktadır. Bunlar Service Manager ve Application Manager olarak adlandırılır. Bu iki bileşen de aynı makine üzerinde veya farklı makineler üzerine dağıtılmış olabilir. Service Manager bileşeni Web servislerinin yüklü olduğu makinede servisleri oluşturmayı ve yönetmeyi sağlar. Application Manager bileşeni ise ADF yüklü makinedeki Web uygulamalarını oluşturmayı ve yönetmeyi sağlar.

GIS Servis kurulumu için buradan ve WEB Application kurulumu için de buradan bileşenlerin doğru yüklenmesine yardımcı olacak bilgiler verilmektedir.

Verileriniz CBS sunucusu (GIS Server) ile aynı yerel ağ üzerinde olmalıdır. Sunucunuzu Manager üzerinden yönetmiyorsanız ağınızda bir ArcGIS Desktop olmalıdır. Verilerinizin ve ArcGIS Desktop uygulamasının diğer CBS sunucu bileşenleri ile aynı makinede bulundurmamalısınız.

Kaynak: http://help.arcgis.com/en/arcgisserver/10.0/help/arcgis_server_dotnet_help/index.html#/Configuring_a_multiple_machine_deployment/0093000000m7000000/

JavascriptSerializer MaxLength Değerinin Aşılması

1 Haz

.Net Framework üzerinde veri transfer mekanizmalarını oluştururken attığımız adımlardan biri de serileştirme işlemidir. Serileştirme işlemlerini Binary, XML veya JSON formatlarında yapabilmekteyiz. Bu yazıda, JSON serileştirme işlemini gerçekleştirirken karşılaşılan bir sorun olan varsayılan olarak ayarlanmış maksimum JSON serileştirme değerinin aşıldığı durumlarda alınan hataları bir ölçüde bertaraf etmeyi inceleyeceğiz.

Örnek uygulamaya geçmeden önce .Net Framework ortamında JSON formatında serileştirme işlemi için gerekli olan ekipmanlardan bahsedelim. Bir nesnenin JSON formatında serileştirilmesi(serialization) veya JSON formatındaki bir verinin .Net nesnesine dönüştürülmesi(deserialization) işlemi için kullanılan referens “System.Web.Extensions”. Projemize bu referansı ekledikten sonra artık ihtiyaç duyduğumuz JavascriptSerializer sınıfına ulaşabiliriz.

Örnek uygulamamızda, verinin büyük olmasını amaçladığımız için bir dosyayı okuyarak JSON formatına dönüştüreceğiz.

Dosya okuma işlemi için aşağıdaki gibi basit bir metod oluşturuyoruz.

private static string readFile()
{
     const string targetDataFile = @"D:\data.txt";

     StreamReader reader = new StreamReader(targetDataFile);

     var result = reader.ReadToEnd();

     return result;
}

Bu metoddan elde ettiğimiz veriyi ise JSON dönüşümünü yapmak için bir başka metod içerisinde kullanıyoruz.

private static string getSerializedFile()
{
    var data = readFile();

    var serializer = new JavaScriptSerializer { MaxJsonLength = int.MaxValue };

    var serialized = serializer.Serialize(data);

    return serialized;
}

Serileştirme işlemi JavascriptSerializer sınıfının Serialize() metodu yardımıyla gerçekleştirilmektedir. JavascriptSerializer sınıfı, MaxJsonLength adında bir property barındırmaktadır. Aksi belirtilmediği taktirde bu property değeri 4MB veriye karşılık gelecek şekilde 2097152 olarak alınır. 4MB’tan fazla veriler için serileştirme sırasında hata verecektir. Bu property için buradan bilgi alabilirsiniz.

Hata InvalidOperationException başlıkı olup, içeriği şu şekildedir: Error during serialization or deserialization using the JSON JavaScriptSerializer. The length of the string exceeds the value set on the maxJsonLength property.

Örnek uygulamamızda MaxJsonLength property değerini int.MaxValue olarak belirledik. Bu da yaklaşık 2GB civarı bir büyüklüktür.