.NET Framework 3.0 ile beraber karşımıza çıkan WCF servisleri aslında çoktan klasik web servislerinin yerini de almış durumda. Tabi ki doğrudan bir karşılaştırma yapmak çok yanlış olacaktır, WCF çok daha geniş kapsamlı bir çerçevede değerlendirilmeli. Silverlight 2.0 tarafına baktığımızda ise istemci ile sunucu arasındaki veri trafiğini klasik ASMX web servislerine bağlayabileceğimiz gibi istersek doğrudan WCF servislerini de kullanabiliyoruz. Bu yazıda Silverlight 2.0 Beta 1 ile WCF servislerininin kullanımına değineceğiz.
WCF servisimizi hazırlayalım.
Visual Studio 2008 içerisinde yarattığımız yeni Silverlight projemize eşlik eden Web Project içerisinde yeni bir WCF servisi yaratıyoruz. Örneğimizde Silverlight tarafından gönderilen iki sayıfa WCF servisi tarafından alınarak sunucu tarafından toplanacak ve geri döndürülecek. Bu çerçevede uygun bir WCF servisini hazırlarken aşağıdaki kodları yazmamız gerekiyor.
[IService.vb]
Imports System.ServiceModel
<ServiceContract()> _
Public Interface IService
<OperationContract()> _
Function Toplama(ByVal x As Integer, ByVal y As Integer) As Integer
End Interface
[Service.vb]
Public Class Service
Implements IService
Public Function Toplama(ByVal x As Integer, ByVal y As Integer) As Integer Implements IService.Toplama
Return x + y
End Function
End Class
WCF servisimiz hazır olduğuna göre Silverlight tarafına geçiş yapabiliriz diye düşünüyorsunuz kesinlikle aldanıyorsunuz. Varsayılan ayarları ile Visual Studio içerisinde herhangi bir WCF servisi yarattılığında wsHttpBinding kullanılır oysa bizim Silverlight tarafında basicHttpBinding'e ihtiyacımız var. O nedenle hemen projemizin Web.Config dosyasına ufak bir yolculuk yaparak aşağıdaki şekilde ayarlarda değişiklik yapmamız gerekiyor.
<services>
<service behaviorConfiguration="ServiceBehavior" name="Service">
<endpoint address="" binding="basicHttpBinding" contract="IService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
Artık tüm ayarlarımız tamamladı. Silverlight 2.0 tarafına rahatlıkla geçebiliriz.
Silverlight 2.0 ve WCF bağlantısı
WCF servisimiz ile Silverlight uygulamamızın aynı domain içerisinde olması şart. Güvenlik kuralları nedeniyle "cross-domain" yani alan adları arası veri trafiği oluşturma şansımız yok. Visual Studio içerisinde Silverlight projenize sağ tıklayarak gelen menüden "Add Service Reference" düğmesine basarak proje içerisinde WCF servisini Silverlight uygulamasına referans olarak ekleyebilirsiniz.
İlk olarak gelin uygulamamızın XAML koduna bir göz atalım.
<UserControl x:Class="SilverlightApplication3.Page"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300">
<Grid x:Name="LayoutRoot" Background="White">
<TextBox Height="29" Margin="72,37,134,0" VerticalAlignment="Top" Text="TextBox" x:Name="Sayi1"/>
<TextBox Height="39" Margin="72,81,134,0" VerticalAlignment="Top" Text="TextBox" x:Name="Sayi2"/>
<Button HorizontalAlignment="Stretch" Margin="114,144,188,122" VerticalAlignment="Stretch" Content="Button" x:Name="Topla"/>
<TextBlock Height="43" Margin="86,0,147,47" VerticalAlignment="Bottom" Text="TextBlock" TextWrapping="Wrap" x:Name="Sonuc"/>
</Grid>
</UserControl>
Şimdi kod tarafına geçerek bir önceki adımda referans olarak projemize eklediğimiz WCF servisini kullanmaya başlayalım.
WithEvents Servis As New WCFServisim.ServiceClient
Yukarıdaki şekli ile servisimizi uygulama içerisinde global olarak tanımlıyoruz. WCF servisimi bu şekilde tanımlamamın aslında önemli bir nedeni var. Birazdan WCF servisi ile istemci tarafından suncuya bir veri talebi gönderdiğimizde, yani toplanacak olan sayıları gönderip toplamı istediğimizde aslında asenkron bir talepte bulunmuş olacağız. Klasik Windows uygulamalarından alıştığımız yapıdan farklı olarak Silverlight 2.0 içerisinde WCF servislerinin kullanımı tamamen asenkron olarak gerçekleşiyor. Durum böyle olunca asenkron bir istek sonrasında sunucudan cevap (veri) geldiğinde bizim kodumuzun da durumdan haberdar edilmesi gerekecek. Söz konusu haber yine WCF servisimize özel olan bir başka event-handler'ın çalıştırılması ise bize ulaştırılacak. Aslında dinamik olarak servisimizi yaratırken event-handler da bağlayabilirdik. Ama Visual Basic ile yukarıdaki gibi bir kullanım çok daha rahat oluyor. C# programcıları dinamik event-handler bağlamayı kullanabilirler.
Global değişkenimizde WCF servisimiz hazır olduğuna göre artık düğmemize bazıldığında söz konusu servisi rahatlıkla kullanabiliriz.
Private Sub Topla_Click(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Topla.Click
Servis.ToplamaAsync(Integer.Parse(Sayi1.Text), Integer.Parse(Sayi2.Text))
End Sub
Gördüğünüz gibi Servis değişkenim üzerinden ToplamaAsync metodunu çağırıyorum. Metodu çalıştırdıktan sonra sunucudan veri geldiğinde bu metoda özel olan ToplamaCompleted event'ı çalıştırılacak.
Private Sub Servis_ToplamaCompleted(ByVal sender As Object, ByVal e As WCFServisim.ToplamaCompletedEventArgs) Handles Servis.ToplamaCompleted
Sonuc.Text = e.Result.ToString
End Sub
ToplamaCompleted event'ına gelen parametrelerden ikincisinin tipine baktığımızda ToplamaCompletedEventArgs ile karşılaşıyoruz. Bu tamamen bizim metodumuza özel bir değişken tipi. Buradan yola çıkarak e.Result dediğimizde ise doğrudan bizim WCF metodumuzun döndürdüğü nesneyi yakalayabiliyoruz. Örneğimizde gelen sonucu uygulama içerisinde bir TextBlock içine yazdırıyoruz.
Kodumuzun tamamına baktığımızda aşağıdaki manzara ile karşılaşıyoruz.
Partial Public Class Page
Inherits UserControl
Public Sub New()
InitializeComponent()
End Sub
WithEvents Servis As New WCFServisim.ServiceClient
Private Sub Topla_Click(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Topla.Click
Servis.ToplamaAsync(Integer.Parse(Sayi1.Text), Integer.Parse(Sayi2.Text))
End Sub
Private Sub Servis_ToplamaCompleted(ByVal sender As Object, ByVal e As WCFServisim.ToplamaCompletedEventArgs) Handles Servis.ToplamaCompleted
Sonuc.Text = e.Result.ToString
End Sub
End Class
Peki ya C# olsaydı?
Visual Basic'e özel yapılar kullandığım için aynı kodun C# muadilini de sizlerle paylaşmak istiyorum. Böylece C# programcıları için anlaşılması çok daha kolay olacaktır.
namespace SilverlightApplication4
{
public partial class Page : UserControl
{
public Page()
{
InitializeComponent();
Topla.Click += new RoutedEventHandler(Topla_Click);
}
void Topla_Click(object sender, RoutedEventArgs e)
{
WCFServisim.ServiceClient Servis = new WCFServisim.ServiceClient();
Servis.ToplamaCompleted += new EventHandler<WCFServisim.ToplamaCompletedEventArgs>(Servis_ToplamaCompleted);
Servis.ToplamaAsync(int.Parse(Sayi1.Text), int.Parse(Sayi2.Text));
}
void Servis_ToplamaCompleted(object sender, SilverlightApplication4.WCFServisim.ToplamaCompletedEventArgs e)
{
Sonuc.Text = e.Result.ToString();
}
}
}
Hepinize kolay gelsin.