WCF ChannelFactory ile proxy oluşturma


82

ChannelFactory'yi kullanarak çağrıları çağırabildiğinizde, hangi koşullar altında bir WCF hizmetinden bir proxy oluşturmayı tercih edeceğinizi merak mı ediyorsunuz?

Bu şekilde, bir proxy oluşturmanıza ve sunucu güncellendiğinde bir proxy oluşturma konusunda endişelenmenize gerek kalmayacak mı?

Teşekkürler


Her zaman ChannelFactory'yi kullanın. Bunu yeterince güçlü bir şekilde ifade edemem.
tom redfern

Yanıtlar:


88

Bir WCF istemcisi oluşturmanın 3 temel yolu vardır:

  1. Visual Studio'nun proxy'nizi oluşturmasına izin verin. Bu, WSDL'yi okuyarak hizmete bağlanan kodu otomatik olarak oluşturur. Hizmet herhangi bir nedenle değişirse, onu yeniden oluşturmanız gerekir. Bunun en büyük avantajı, kurulumunun kolay olmasıdır - VS'nin bir sihirbazı vardır ve hepsi otomatiktir. Dezavantajı, tüm zor işleri sizin için yapması için VS'ye güvenmenizdir ve bu nedenle kontrolü kaybedersiniz.

  2. ChannelFactoryBilinen bir arayüzle kullanın . Bu, hizmeti (hizmet sözleşmesi) tanımlayan yerel arayüzlere sahip olmanıza dayanır. En büyük avantaj, değişimi çok daha kolay yönetebilmesidir - yine de değişiklikleri yeniden derlemeniz ve düzeltmeniz gerekir, ancak şimdi kodu yeniden oluşturmuyorsunuz, yeni arayüzlere referans veriyorsunuz. Genel olarak bu, hem sunucuyu hem de istemciyi kontrol ettiğinizde kullanılır, çünkü her ikisi de birim testi için çok daha kolay alay edilebilir. Ancak arayüzler herhangi bir hizmet için yazılabilir, hatta REST olanlar bile - bu Twitter API'ye bir göz atın .

  3. Kendi proxy'nizi yazın - bunu yapmak oldukça kolaydır, özellikle REST hizmetleri için HttpClientveya WebClient. Bu size en ince tahıl denetimini sağlar, ancak çok sayıda hizmet API'sinin dizelerde yer alması pahasına. Örneğin: var content = new HttpClient().Get("http://yoursite.com/resource/id").Content;- API'nin ayrıntıları değişirse, çalışma zamanına kadar bir hatayla karşılaşmazsınız.

Kişisel olarak 1. seçeneği hiç sevmedim - otomatik olarak oluşturulan koda güvenmek dağınıktır ve çok fazla kontrolü kaybeder. Ayrıca, sık sık serileştirme sorunları yaratır - sonuçta iki özdeş sınıf (biri sunucu kodunda, biri otomatik olarak oluşturulmuş) ortaya çıkar, ancak bu bir sıkıntıdır.

Seçenek 2 mükemmel olmalı, ancak Kanallar biraz fazla sınırlayıcıdır - örneğin , HTTP hatalarının içeriğini tamamen kaybederler . Bu, servisi tanımlayan arayüzlere sahip olmanın kodlamanın ve bakımının çok daha kolay olduğunu söyledi.


4
@MurHaf Nope - bu cevap tamamen benim işim. HER ZAMAN başkalarının katkılarına bağlıyorum. Bu cevabı .Net'te çeşitli işlerde SOAP servisleriyle yıllarca çalışarak yazdım. Bağlandığınız makale Mart 2013'e ait, cevabım ise Nisan 2010'da - 3 yıl önce yazılmış! İntihal olmuşsa beni kopyaladı. Yapması çok kolay olduğu için suçlamadan önce tarihleri ​​kontrol etmelisiniz.
Keith

@MurHaf aynı sonuçlara bile varmıyoruz - bu makale bir proxy'nin otomatik olarak oluşturulmasını (seçenek 1) 'basit' olarak öneriyor. Kurulumu kolay, ancak dağınık ve bakımı zor bir şey olarak tanımlıyorum. Kendi vekilinizi yazmaktan bile bahsetmiyor (seçenek 3).
Keith

1
Bir istemciyi "yazmanın" en yaygın yollarından biri olduğu için SvcUtil'den de bahsedilmesi gerektiğini düşünüyorum.
Mare Infinitus

21

ChannelFactory'yi MetadataResolver.Resolve yöntemi ile birlikte kullanıyorum. İstemci yapılandırması can sıkıcı, bu yüzden sunucudan ServiceEndpoint'imi alıyorum.

ChannelFactory (Of T) kullandığınızda, T, projenizdeki bir referanstan alabileceğiniz orijinal sözleşmedir veya oluşturulmuş bir sözleşme örneğidir. Bazı projelerde, sözleşme dll'sine referans ekleyemediğim için kodu bir Servis Referansından oluşturdum. Hatta hizmet referansı ile bir eşzamansız sözleşme oluşturabilir ve bu sözleşme arayüzünü ChannelFactory ile kullanabilirsiniz.

Benim için ChannelFactory'yi kullanmanın ana amacı WCF istemci yapılandırma bilgilerinden kurtulmaktı. Aşağıdaki örnek kodda, yapılandırma olmadan bir WCF istemcisine nasıl ulaşılacağını görebilirsiniz.

Dim fixedAddress = "net.tcp://server/service.svc/mex"
Dim availableBindings = MetadataResolver.Resolve(GetType(ContractAssembly.IContractName), New EndpointAddress(fixedAddress))
factoryService = New ChannelFactory(Of ContractAssembly.IContractName)(availableBindings(0))
accesService = factoryService.CreateChannel()

Son projemde, availableBindings, varsa net.tcp veya net.pipe kullanmak için kontrol edilir. Bu şekilde, ihtiyaçlarım için mevcut en iyi ciltlemeyi kullanabilirim. Ben sadece sunucuda bir meta veri uç noktasının var olduğuna güveniyorum.

Umarım bu yardımcı olur

BTW, bu .NET 3.5 kullanılarak yapılır. Ancak 4.0 ile de çalışır.


Harika şey. Config için MetadataResolver.Resolve kullanıyorum ama sunucudan bağlanmayı çözmeyi düşünmedim. Çok iyi nokta!
Sleeper Smith

bahsetmek için olumlu oyThe main point of using ChannelFactory to get rid of the WCF client config
Kurubaran

11

Peki kullanmak ChannelFactory<T>için hizmet ve müşteri arasında sözleşme derlemelerini paylaşmaya istekli olmalısınız. Bu sizin için uygunsa ChannelFactory<T>, size biraz zaman kazandırabilir.


@Charles - bunun neden doğru olmadığını açıklayabilir misiniz?
Aran Mulholland

6
@Aran: Andrew'un söylediği şeyin doğru olduğunu düşünüyorum - sözleşme sınıflarının kopyalarını oluşturmak istemiyorsanız, orijinallere erişiminizin olması gerekir. Öyle ya da böyle bu sözleşmeli sınıflara sahip olmanız gerektiği doğru. Bunları oluşturabilir, elle yazabilir veya hizmet kaynak kodunu (aynı dilde ise) alabilirsiniz. Montajları paylaşmak en kolay yoldur, ancak bu her zaman mümkün değildir. (Belki Andrew'u kelimenin tam anlamıyla alıyorum, ancak burada açıklık önemlidir.)
Igby Largeman

2
@Charles ok, yani derlemelere erişiminiz olmasa bile T arayüzünü elle kodlayıp sonra onu kullanarak ChannelFactory <T> kullanabileceğinizi söylüyorsunuz.
Aran Mulholland

1
@Aran: evet, ya elle kodlayarak ya da svcutil gibi bir araç kullanarak (hizmetin çalıştığını ve erişilebilir olduğunu varsayarak).
Igby Largeman

9

Proxy zaman uyumsuz işlevler oluşturacak ve bunun için hoş bir durum.


2
evet - aynı zamanda, hem Visual Studio'nun "Hizmet Referansı Ekle" hem de komut satırındaki svcutil.exe yapılandırmanızı tanınmayacak şekilde keser .... en azından svcutil.exe ile bir "/ noconfig" anahtarı tanımlayabilirsiniz .....
marc_s

1
ChannelFactory ayrıca eşzamansız yöntemler de sağlar: msdn.microsoft.com/en-us/library/ms731177.aspx Ancak, eşzamanlı yöntemleri çağıracak ThreadPool kullanarak bir eşzamansız sınıf oluşturmak için bir T4 şablonu kullanmayı tercih ediyorum.
SandRock

1
Güncelleme olarak: .NET 4.5 ile ChannelFactory <T> görev tabanlı zaman uyumsuz işlevleri de destekler.
gimpf

8

Cevabım Keith ve Andrew Hare'in bir tür özeti. cevaplarının .

Sunucuyu kontrol etmiyorsanız, ancak yalnızca WSDL / URL'niz varsa, Visual Studio veya svcutil kullanarak proxy oluşturun. (Svcutil daha iyi çalıştığında Visual Studio'nun bazen başarısız olduğunu unutmayın).

Hem sunucuyu hem de istemciyi kontrol ettiğinizde, arayüzleri / sözleşmeleri paylaşın ve ChannelFactory'yi arayın
.


2

Bu sadece kazanılan zaman meselesi değil. WSDL tarafından oluşturulan proxy'yi kullanmak tehlikelidir çünkü hizmet referansını güncellemeyi unutursanız çözümü tutarsız bir durumda bırakabilirsiniz. Her şey derlenir ama hizmet sözleşmesi bozulur. Mümkün olduğunca ChannelFactory kullanmayı kesinlikle öneririm, hayatınızı çok kolaylaştırırsınız.

Olası bir alternatif, projenizi her oluşturduğunuzda proxy oluşturmak için SVCUtil yardımcı programını çağıran önceden oluşturulmuş bir komut dosyası yazmak olabilir, ancak yine de ChannelFactory çok daha düzgün ve zariftir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.