Bir WCF Hizmetine İstemci Oluşturma

Hand drawing chart in whiteboard

   Windows Communication Foundation’ın detaylarını sizlerle paylaşmayı hedeflediğim makale serisinde daha önce sizlerle bir WCF hizmetini gerek app.config dosyası üzerinden gerekse de programsal olarak nasıl oluşturabileceğinizi paylaşmıştım. Giriş düzeyinde gördüğümüz WCF hizmeti oluşturma konusunda ilerleyen makalelerde daha detaylı bilgiler paylaşmayı planlamakla birlikte, bu konudaki ileri tekniklere/ detaylara geçmeden önce isterseniz birlikte bir WCF hizmet istemcisini nasıl oluşturabileceğimizi görelim.

   Bir WCF hizmetine istemci oluşturmada 3 temel yöntem bulunmakta; komut satırından service model meta veri hizmet aracını kullanarak, Visual Studio içerisinde yer alan sihirbazları kullanarak ya da uygulamamız içerisinden programsal olarak. İsterseniz bu 3 yöntemin neler olduğunu sırasıyla görelim:

   İlk yöntemimiz olan service model meta veri hizmet aracını (Svcutil.exe) komut satırından kullanabilmenin en kolay yolu yeni bir Visual Studio Command Prompt oturumu başlatmaktır. Bilgisayarınıza herhangi bir Visual Studio sürümünü kurmanızla birlikte başlat menüsünde Microsoft Visual Studio 2010 ->  Visual Studio Tools klasörü altına yerleşen Visual Studio Command Prompt ,aslında Visual Studio ile birlikte gelen araçları kullanmamız için gerekli MSDOS path ve değişken tanımlarını yapan bir batch dosyasından farklı bir şey değildir; ama bu haliyle bile bizim için oldukça kullanışlı.

   Svcutil uygulaması, Microsoft tarafından geliştirilmiş ve WCF hizmetince yayınlanan meta veriyi kullanarak otomatik olarak istemci oluşturabilen bir konsol uygulamasıdır. İstemci kodunu otomatik üretebilmesi için gerekli bilgiyi alacağı bir meta verinin bulunması gerektiğini düşünecek olursak, hizmetimizin gerekli olan bu meta veriyi online ya da offline olarak bizlere sağlıyor olması gerekli. Serinin ilk iki makalesini hatırlayacak olursanız bir WCF hizmetinin meta verisi iki şekilde yayınlayabilmekteydik; meta veri değişim uç noktası (Metadata Exchange, MEX endpoint) ve servis meta veri davranışı (ServiceMetadataBehavior). Svcutil uygulaması her iki yöntemi de destekleyerek tanımlaması verilen WCF hizmetine bağlanmayı sağlayacak olan kodu otomatik olarak üretebilir.

   Makalemin geri kalanında bu iki meta veri yayınlama yönteminden en az birisinin WCF hizmetinizde aktif ya da meta verinizin wsdl/xsd dosyaları olarak yerel bilgisayarımızda ulaşılabilir bir yerde olduğunu varsayıyorum.

Svcutil.exe <hizmet Meta veri Değişim (MEX) ya da HTTP GET adresi>

   Yukarıda en basit haliyle Svcutil aracının komut satırından nasıl tetiklenebileceğini görmektesiniz. Uygulamaya parametre olarak MEX adresi verilebileceği gibi http get yöntemi ile paylaşılan meta verinin adresi de verilebilir. Bu bilgi uygulama tarafından kullanılarak meta veri alınır ve meta veri ile belirtilen kontrata uygun bir istemci oluşturulur. Svcutil uygulamasını kullanarak otomatik olarak istemci üretebilmek için her zaman online olarak meta veriye ulaşmak zorunda değiliz. Güvenlik nedeniyle meta veri erişiminin kapatıldığı ya da kontrolümüzün dışında olan ve meta verisi yayınlanmamış WCF hizmetlerinin kullanılması gerektiği senaryolar da düşünülerek, aynı işlem çevrim dışı olarak bilgisayarınızda bulunan web hizmeti tanım dili (Web Services Description Language, WSDL) ve xml şema tanım dili (XML Schema definition language, XSD) dosyaları kullanılarak da yapılabilmektedir. Aşağıda bu şekilde kod üretimine örnek bir kullanım bulabilirsiniz;

Svcutil.exe <Bilgisayarınızda bulunan WSDL ve XSD dosyalarının listesi>

   Yukarıdaki iki yöntemden senaryonuza uygun olanı kullanmamız sonrasında Svcutil uygulaması WCF hizmetine bağlanmak için kullanabileceğiniz bir istemciye ait kodların bulunduğu bir kaynak dosyası üretecektir.

   Svcutil uygulaması yukarıdaki parametreler dışında kullanılacak olan programlama dili, assembly gibi üretilecek olan kaynak kod dosyasını özelleştirebilmeniz için farklı parametreler de kabul etmektedir. Hatta kod üretirken mevcutta bulunan uygun sınıflarımızı kullanmak isteyip istemeyeceğimizi dahi belirtebiliriz. Pek çok parametreye sahip olan bu araç hakkında MSDN sitesinde yer alan uygulama dokümantasyonu sizlere kullanabileceğiniz parametreler konusunda yardımcı olacaktır.

   Aynı bir WCF hizmetinde olduğu gibi, WCF istemcisinde de gerekli olan yapılandırma bilgisi uygulama yapılandırma dosyasında (app.config, web.config) tutulabilmektedir. Bu dosyanın da otomatik olarak üretilmesini destekleyen svcutil uygulaması aşağıdaki şekildeki bir kullanım sonrasında bize gerekli olan yapılandırma dosyasını üretecektir;

Svcutil.exe <dosya1 [,dosya2]>

   Aşağıda, önceki makalelerimde sizlerle paylaşmış olduğum örnek WCF hizmetine bağlanmakta kullanılacak olan ve svcutil uygulamasınca otomatik üretilmiş olan OrnekHizmetClient sınıfı ile bu sınıfı üretmekte kullandığım komut satırını bulabilirsiniz;

svcutil http://localhost:1234/WCFOrnekleri
//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.1
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------



[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace="http://www.enterprisecoding.com/WCFOrnekleri", ConfigurationName="IOrnekHizmet")]
public interface IOrnekHizmet
{
    
    [System.ServiceModel.OperationContractAttribute(Action="http://www.enterprisecoding.com/WCFOrnekleri/IOrnekHizmet/Say", ReplyAction="http://www.enterprisecoding.com/WCFOrnekleri/IOrnekHizmet/SayResponse")]
    int Say();
}

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public interface IOrnekHizmetChannel : IOrnekHizmet, System.ServiceModel.IClientChannel
{
}

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public partial class OrnekHizmetClient : System.ServiceModel.ClientBase<IOrnekHizmet>, IOrnekHizmet
{
    
    public OrnekHizmetClient()
    {
    }
    
    public OrnekHizmetClient(string endpointConfigurationName) : 
            base(endpointConfigurationName)
    {
    }
    
    public OrnekHizmetClient(string endpointConfigurationName, string remoteAddress) : 
            base(endpointConfigurationName, remoteAddress)
    {
    }
    
    public OrnekHizmetClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) : 
            base(endpointConfigurationName, remoteAddress)
    {
    }
    
    public OrnekHizmetClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : 
            base(binding, remoteAddress)
    {
    }
    
    public int Say()
    {
        return base.Channel.Say();
    }
}

   Gördüğünüz gibi oluşturulan kod 3 sınıftan oluşmakta;

  • Gerekli WCF meta verileri eklenmiş olan ve servisimizin kontratını belirten IOrnekHizmet arayüzü,
  • IOrnekHizmetChannel istemci kanalı arayüzü
  • WCF hizmetimiz ile iletişimi saylayacak olan OrnekHizmetClient istemci sınıfı

  Otomatik olarak üretilen bu arayüz ve sınıfları makalemin ilerleyen bölümlerinde birlikte inceleyeceğiz; fakat bu detaya geçmeden önce isterseniz bir de Visual Studio’yu kullanarak bir istemci nasıl oluşturabileceğimizi görelim.

   Visual Studio içerisinde istemci uygulamamızı geliştiriyorken hizmetimize bağlanmakta kullanacağımız kodları üretmemiz çok daha kolay. Visual Studio yukarıdaki uygulama ve uygulamaya geçilen parametreleri bizlere kullanımı oldukça kolay olan bir arayüz üzerinden sorarak, girdimiz bilgiler doğrultusunda arka planda benzer işlerle WCF istemci kodunu üretmektedir.

   Visual Studio içerisinden hizmet referansı ekleme sihirbazı ile hizmetinize bağlanmada kullanacağınız istemci kodlarını otomatik olarak oluşturabilirsiniz. Bu sihirbazı kullanabilmek için istemci projenize sağ tıklayarak, gelen menüden “Add Service Reference…” seçilmeli;

 

Visual Studio hizmet referansı ekleme sihirbazını projeye sağ tıklanarak gelen menüden başlatılabilir

   Mümkün olduğunca sade ve kolay kullanımı hedefleyen hizmet referansı ekleme diyaloğu bizden istemci oluşturulacak olan WCF hizmet meta veri adresini ve oluşturulacak olan kodun hangi namespace altında olacağını soracaktır;

image

   Bu diyalogda ayrıca belirttiğimiz meta veri içerisinde yer alan hizmet(ler) ile bu hizmet(ler) içerisinde yer alan fonksiyonaliteler de listelenecektir. Diyalogda yer alan “Advanced…” butonu bizlere oluşturulacak olan kod hakkında daha detaylı yapılandırma seçenekleri sunan “Service Reference Settings” diyalogunu açacaktır;

İleri düzey işlemlerin yapılabileceği

  Komut satırından scvutil aracına verebileceğimiz parametrelerle paralellik gösteren bu diyalogda, oluşturulacak sınıfların hangi düzeyde erişime sahip olacağından mevcut bir assembly içerisindeki türlerin kullanılmasına kadar pek çok ileri düzey ayar yapılabilmekte.

   Diyalog üzerindeki “generate asyncronous operations” seçeneği dikkatinizi çekmiştir. Diyalog üzerindeki bu seçeneğin seçilmesi durumunda oluşturulacak koda hizmetin asenkron olarak çağırılabilmesini sağlayacak yardımcı fonksiyonlar eklenecektir. Bu fonksiyonlar kullanılarak hizmetin çağrılması sırasında kullanıcılarınızın başka işler yapabilmesi ve/veya arayüzün kilitlenmemesi sağlanabilir. Diyalog üzerinde yer alan “Add Web Reference…” butonu ise .Net framework 2.0 uyumlu bir servis istemcisi üretilmesini sağlayacaktır.

   İhtiyaçlarınız doğrultusunda ayarlamalarınızı yaparak ok butonu yardımıyla diyalogdan çıkmanız durumunda ,Visual Studio gerekli olan dosyaları üreterek projeniz içerisinde “Service References” klasörü  altına atacaktır.

Hizmet refenasının eklenmesi sonrasında proje

   Hizmet referansının eklenmesi sonrasında projeniz yukarıdaki gibi görünecektir. Bu resimde gördüğünüz service references klasörü altında yer alan Com.Enterprisecoding.WCFOrnekleri.OrnekHizmet girdisi de aslında bir klasördür. İçerisinde servis tanım dosyaları, yapılandır ve kodların yer aldığı bu klasör Visual Studio tarafından bu şekilde gösterilmektedir. Solution Explorer penceresinde sağ üst köşede yer alan “Show All Files” butonuna basılacak olursa bu klasör altındaki bahsettiğim dosyalar da görülebilir.

Solution Explorer penceresinde yeralan "tüm dosyaları göster" butonu

 

   Aşağıda “Show All Files” butonuna basılması sonrası dosyaların nasıl göründüğüne dair bir ekran görüntüsü bulabilirsiniz;Tüm dosyaların gösterilmesi sonrasında Solution Explorer

   Ekran görüntüsünde Com.Enterprisecoding.WCFOrnekleri.OrnekHizmet klasörü altında yer alan dosyalardan References.cs içerisinde otomatik üretilmiş olan kodları bulundurmaktadır.

    Dilerseniz hizmet istemcinizi oluşturduktan sonra hizmet istemcinize ait klasöre sağ tıklayarak, gelen menüden hizmet referansını güncelleyebilir ya da yapılandırmasını değiştirebilirsiniz;

image

   Visual Studio içerisinde yukarıda sıraladığım işlemlerin yapılması sonrasında oluşan istemci kodunun uygulamamız içerisinde kullanılması oldukça kolay. Hizmet istemcisi hakkındaki bilgiler (kullanılacak olan protokol, uç noktası adresi v.b.) uygulamanın yapılandırma dosyasına eklendiği için kod içerisinde yeni bir örneğini oluşturmak oldukça kolay. Aşağıdaki kod örneği oluşturulan hizmet istemcisinin kullanımının ne kadar kolay olduğunu sizlere gösterecektir;

static void Main(string[] args) { 
    var istemci = new OrnekHizmetClient();

istemci.Say()

    Console.WriteLine(); 
    Console.WriteLine("Uygulamayı sonlandırmak için herhangi bir tuşa basınız"); 
    Console.ReadKey();
}

   Gördüğünüz gibi internet/intranet üzerinde yer alan hizmeti aynı normal bir sınıfın fonksiyonlarını kullanır gibi rahatlıkla kullanabilmekteyim. Burada da, sunucu tarafını anlattığım makalelerimde sizlerle paylaştığım gibi, yapılandırma bilgisi ve uç nokta adresi kod içerisinden de geçilebilmektedir. Herhangi bir yapılandırma bilgisi ve/veya uç noktası belirtilmemesi durumunda uygulamanın yapılandırma dosyasında tür için tanımlanmış olan değerler kullanılacaktır.

   Makalemde sizlerle paylaştığım yukarıdaki iki yöntem bizler adına kodlar üreterek hizmetlere hızlıca bağlanmamızı sağlamakta. Bazı durumlarda iş mantığımız gereği oluşan sınıfların içeriğine ve iş akışlarına müdahale etmemiz gerekebilir.  Bu gibi durumlarda kodu otomatik üretmek yerine kendimizin de yazması mümkündür.

   Her WCF uygulamasında olduğu gibi istemcimizin kodunu yazarken de öncelikle kullanacağımızı bağlayıcı ve hizmetin uç noktası adresini belirtmeliyiz;

WSHttpBinding baglayici = new WSHttpBinding();
EndpointAddress ucNokta = new EndpointAddress("http://localhost:1234/WCFOrnekleri/OrnekHizmet");

  Dikkat ettiyseniz uç nokta adresini verirken temel adresten hemen sonra kullanacağım uç noktası adresi de eklenmiş durumda. Bu noktadan son yapmamız gereken hizmet istemcimizi bizim için üretecek olan bir fabrika örneği oluşturmak. .Net framework ile birlikte gelen generik ChannelFactory sınıfı bizim adımıza arayüzünü verdiğimiz hizmete belirtilen bağlayıcı ve uç noktayla bağlanacak istemciler üretmekte.

ChannelFactory<IOrnekHizmet> istemciFabrikasi = new ChannelFactory<IOrnekHizmet>(baglayici, ucNokta);

   Yukarıdaki kod IOrnekHizmet arayüzüyle belirtilen kontrata uygun olarak verilen bağlayıcı ve uç nokta ile çalışacak olan istemciler üretebilecek bir istemci fabrikası oluşturmakta. Iistemci ve sunucu tarafı kodlarının elimizde olduğu bu makalede IOrnekHizmet arayüzünü sunucu projemiz içerisinde istemci projemize kopyalamamız yeterli olacaktır. Bu adım sonrasında her istemci üretilmesi gereken noktada istemci fabrikasına ait CreateChannel fonksiyonu kullanılabilir;

IOrnekHizmet istemci = istemciFabrikasi.CreateChannel();

   Bu kodun her kullanıldığı yerde önceden fabrikaya verilmiş olan bilgilerle hizmete veri gönderecek bir kanal açılacaktır. Bu noktadan sonra istemci örneği üzerinden IOrnekHizmet kontrattıyla belirtilen tüm fonksiyonaliteler kullanılabilir olacaktır.

   Tüm resmi bir araya toplayacak olursak, programsal olarak bir istemci oluşturmanın aslında oldukça kolay olduğunu sizlerde görebilirsiniz;

WSHttpBinding baglayici = new WSHttpBinding();
EndpointAddress ucNokta = new EndpointAddress("http://localhost:1234/WCFOrnekleri/OrnekHizmet");

ChannelFactory<IOrnekHizmet> istemciFabrikasi = new ChannelFactory<IOrnekHizmet>(baglayici, ucNokta);
var istemci = istemciFabrikasi.CreateChannel();

istemci.Say();

   WCF serimizde geldiğimiz noktada gerek istemci gerekse de sunucu tarafında temel düzeyde bir etkileşim için gerekli bilgiye aktarabildiğimi umuyorum. İlerleyen makalelerimizde gerek hizmet örneği yönetimi gerekse de istemci yönetimi konularına daha detaylı olarak değineceğiz.

Fatih Boy

Ankara'da yaşayan Fatih, bir kamu kurumunda danışman olarak çalışmaktadır. ALM süreçleri, kurumsal veri yolu sistemleri, kurumsal altyapı ve yazılım geliştirme konularında destek vermektedir. Boş zamanlarında açık kaynak kodlu projeler geliştirmeyi ve bilgisini yazdığı makalelerle paylaşmayı seven Fatih, aynı zamanda Visual C# ve Visual Studio teknolojileri konusundan Microsoft tarafından altı yıl üst üste MVP (En Değerli Profesyonel) ödülüne layık görülmüştür. İş hayatı boyunca masaüstü uygulamaları, web teknolojileri, akıllı istemciler gibi konularda Asp.Net, Php, C#, Java programlama dilleri ve MySql, MsSql ve Oracle gibi veritabanı yönetim yazılımları ile çalışmıştır. İngilizce ve Türkçe olarak yayınlanan makalelerini gerek İngilizce bloğunda, gerekse de Türkçe bloğunda bulabileceğiniz gibi web sitesinden de açık kaynak kodlu geliştirdiği yazılımlarına ulaşabilirsiniz. vCard - Twitter - Facebook - Google+

1 Yorum

  1. Esat   •  

    Paylaşım için teşekkürler…

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir