Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Windows Communication Foundation (WCF), dağıtılmış bir ortamdaki sunucular ve istemciler arasında yönetilen kod çağrıları için Dağıtılmış Bileşen Nesne Modeli (DCOM) üzerinden önerilir. Bu makalede, aşağıdaki senaryolar için kodu DCOM'dan WCF'ye nasıl geçireceğiniz gösterilmektedir:
- Uzak hizmet istemciye değere göre bir nesne döndürür.
- İstemci, uzak hizmete değere göre bir nesne gönderir.
- Uzak hizmet, istemciye bir nesneyi başvuru olarak döndürür.
Güvenlik nedeniyle, WCF'de istemcinin hizmete bir nesneyi referansla göndermesine izin verilmez. wcf'de çift yönlü hizmet kullanılarak istemci ve sunucu arasında ileri geri konuşma gerektiren bir senaryo elde edilebilir. Çift yönlü hizmetler hakkında daha fazla bilgi için bkz. Çift Yönlü Hizmetler.
Bu hizmetler için WCF hizmetleri ve istemcileri oluşturma hakkında daha fazla bilgi için bkz. Temel WCF Programlama, Hizmetleri Tasarlama ve Uygulama ve İstemci Oluşturma.
DCOM örnek kodu
Bu senaryolar için WCF kullanılarak gösterilen DCOM arabirimleri aşağıdaki yapıya sahiptir:
[ComVisible(true)]
[Guid("AA9C4CDB-55EA-4413-90D2-843F1A49E6E6")]
public interface IRemoteService
{
Customer GetObjectByValue();
IRemoteObject GetObjectByReference();
void SendObjectByValue(Customer customer);
}
[ComVisible(true)]
[Guid("A12C98DE-B6A1-463D-8C24-81E4BBC4351B")]
public interface IRemoteObject
{
}
public class Customer
{
}
Hizmet, değere göre bir nesne döndürür
Bu senaryoda bir hizmeti ararsınız ve bu yöntem, sunucudan istemciye değer olarak geçirilen bir nesne döndürür. Bu senaryo aşağıdaki COM çağrısını temsil eder:
public interface IRemoteService
{
Customer GetObjectByValue();
}
Bu senaryoda istemci, uzak hizmetten bir nesnenin seri durumdan çıkarılmış bir kopyasını alır. İstemci, hizmete geri dönmeden bu yerel kopyayla etkileşimde bulunabilir. Yerel kopyadaki yöntemler çağrıldığında, hizmetin hiçbir şekilde dahil olmayacağı istemciye garanti edilir. WCF her zaman hizmetten nesneleri değere göre döndürür, bu nedenle aşağıdaki adımlar normal bir WCF hizmeti oluşturmayı açıklar.
1. Adım: WCF hizmet arabirimini tanımlama
WCF hizmeti için bir ortak arabirim tanımlayın ve [ServiceContractAttribute] özniteliğiyle işaretleyin. İstemcilere göstermek istediğiniz yöntemleri [OperationContractAttribute] özniteliğiyle işaretleyin. Aşağıdaki örnekte, bir istemcinin çağırabileceği sunucu tarafı arabirimini ve arabirim yöntemlerini tanımlamak için bu özniteliklerin kullanılması gösterilmektedir. Bu senaryo için kullanılan yöntem kalın olarak gösterilir.
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
. . .
[ServiceContract]
public interface ICustomerManager
{
[OperationContract]
void StoreCustomer(Customer customer);
[OperationContract] Customer GetCustomer(string firstName, string lastName);
}
2. Adım: Veri sözleşmesini tanımlama
Daha sonra hizmet için verilerin hizmetle istemcileri arasında nasıl değiş tokuş yapılacağını açıklayan bir veri sözleşmesi oluşturmanız gerekir. Veri sözleşmesinde açıklanan sınıflar [DataContractAttribute] özniteliğiyle işaretlenmelidir. hem istemci hem de sunucu tarafından görünmesini istediğiniz tek tek özellikler veya alanlar [DataMemberAttribute] özniteliğiyle işaretlenmelidir. Veri sözleşmesindeki bir sınıftan türetilen türlere izin vermek istiyorsanız, bunları [KnownTypeAttribute] özniteliğiyle tanımlamanız gerekir. WCF yalnızca hizmet arabirimindeki türleri ve bilinen türler olarak tanımlanan türleri serileştirir veya seri durumdan çıkartır. Bilinen bir tür olmayan bir tür kullanmayı denerseniz, bir özel durum oluşur.
Veri sözleşmeleri hakkında daha fazla bilgi için bkz. Veri Sözleşmeleri.
[DataContract]
[KnownType(typeof(PremiumCustomer))]
public class Customer
{
[DataMember]
public string Firstname;
[DataMember]
public string Lastname;
[DataMember]
public Address DefaultDeliveryAddress;
[DataMember]
public Address DefaultBillingAddress;
}
[DataContract]
public class PremiumCustomer : Customer
{
[DataMember]
public int AccountID;
}
[DataContract]
public class Address
{
[DataMember]
public string Street;
[DataMember]
public string Zipcode;
[DataMember]
public string City;
[DataMember]
public string State;
[DataMember]
public string Country;
}
3. Adım: WCF hizmetini uygulama
Ardından, önceki adımda tanımladığınız arabirimi uygulayan WCF hizmet sınıfını uygulamanız gerekir.
public class CustomerService: ICustomerManager
{
public void StoreCustomer(Customer customer)
{
// write to a database
}
public Customer GetCustomer(string firstName, string lastName)
{
// read from a database
}
}
4. Adım: Hizmeti ve istemciyi yapılandırma
WCF hizmetini çalıştırmak için, belirli bir WCF bağlamasını kullanarak bu hizmet arabirimini belirli bir URL'de kullanıma sunan bir uç nokta bildirmeniz gerekir. Bağlama, istemcilerin ve sunucunun iletişim kurması için aktarım, kodlama ve protokol ayrıntılarını belirtir. Genellikle hizmet projesinin yapılandırma dosyasına (web.config) bağlamalar eklersiniz. Aşağıda örnek hizmet için bir bağlama girdisi gösterilmektedir:
<configuration>
<system.serviceModel>
<services>
<service name="Server.CustomerService">
<endpoint address="http://localhost:8083/CustomerManager"
binding="basicHttpBinding"
contract="Shared.ICustomerManager" />
</service>
</services>
</system.serviceModel>
</configuration>
Ardından, istemciyi hizmet tarafından belirtilen bağlama bilgileriyle eşleşecek şekilde yapılandırmanız gerekir. Bunu yapmak için, istemcinin uygulama yapılandırması (app.config) dosyasına aşağıdakileri ekleyin.
<configuration>
<system.serviceModel>
<client>
<endpoint name="customermanager"
address="http://localhost:8083/CustomerManager"
binding="basicHttpBinding"
contract="Shared.ICustomerManager"/>
</client>
</system.serviceModel>
</configuration>
5. Adım: Hizmeti çalıştırma
Son olarak, hizmet uygulamasına aşağıdaki satırları ekleyerek ve uygulamayı başlatarak konsol uygulamasında kendi kendine barındırabilirsiniz. WcF hizmet uygulamasını barındırmanın diğer yolları hakkında daha fazla bilgi için , Barındırma Hizmetleri.
ServiceHost customerServiceHost = new ServiceHost(typeof(CustomerService));
customerServiceHost.Open();
6. Adım: İstemciden hizmeti çağırma
İstemciden hizmeti çağırmak için hizmet için bir kanal fabrikası oluşturmanız ve bir kanal talep etmeniz gerekir; bu, GetCustomer yöntemini doğrudan istemciden çağırmanızı sağlar. Kanal, hizmetin arabirimini uygular ve temel istek/yanıt mantığını sizin için işler. Bu yöntem çağrısının dönüş değeri, hizmet yanıtının seri durumdan çıkarılmış kopyasıdır.
ChannelFactory<ICustomerManager> factory =
new ChannelFactory<ICustomerManager>("customermanager");
ICustomerManager service = factory.CreateChannel();
Customer customer = service.GetCustomer("Mary", "Smith");
İstemci sunucuya değere göre bir nesne gönderir
Bu senaryoda, istemci sunucuya değere göre bir nesne gönderir. Bu, sunucunun nesnenin seri durumdan çıkarılmış bir kopyasını alacağı anlamına gelir. Sunucu bu kopyadaki yöntemleri çağırabilir ve istemci koduna geri çağrı yapılmayacağı garanti edilir. Daha önce belirtildiği gibi, normal WCF veri değişimleri değere göre yapılır. Bu, bu nesnelerden birinde çağrılan yöntemlerin yalnızca yerel olarak yürütülmesini garanti eder; istemcide kod çağırmaz.
Bu senaryo aşağıdaki COM yöntemi çağrısını temsil eder:
public interface IRemoteService
{
void SendObjectByValue(Customer customer);
}
Bu senaryo, ilk örnekte gösterildiği gibi aynı hizmet arabirimini ve veri sözleşmesini kullanır. Ayrıca, istemci ve hizmet de aynı şekilde yapılandırılır. Bu örnekte, nesneyi göndermek ve aynı şekilde çalıştırmak için bir kanal oluşturulur. Ancak, bu örnekte, bir nesneyi değer olarak geçirerek hizmeti çağıran bir istemci oluşturacaksınız. İstemcinin hizmet sözleşmesinde çağıracağı hizmet yöntemi kalın olarak gösterilir:
[ServiceContract]
public interface ICustomerManager
{
[OperationContract] void StoreCustomer(Customer customer);
[OperationContract]
Customer GetCustomer(string firstName, string lastName);
}
İstemciye değere göre nesne gönderen kod ekleme
Aşağıdaki kodda, istemcinin yeni bir değere göre müşteri nesnesi oluşturması, hizmetle iletişim kurmak için bir kanal oluşturması ICustomerManager ve müşteri nesnesini buna göndermesi gösterilmektedir.
Müşteri nesnesi dizileştirilecek ve hizmete gönderilecek, burada hizmet tarafından bu nesnenin yeni bir kopyası olarak seri durumdan çıkarılacak. Hizmetin bu nesnede çağıracağı tüm yöntemler yalnızca sunucuda yerel olarak yürütülür. Bu kodun türetilmiş bir tür (PremiumCustomer) göndermeyi gösterdiğini unutmayın. Hizmet sözleşmesi bir Customer nesne bekler, ancak hizmet veri sözleşmesi de izin verildiğini KnownTypeAttribute belirtmek için [PremiumCustomer] özniteliğini kullanır. WCF, bu hizmet arabirimi aracılığıyla başka bir türü seri hale getirme veya seri durumdan çıkarma girişimlerinde başarısız olur.
PremiumCustomer customer = new PremiumCustomer();
customer.Firstname = "John";
customer.Lastname = "Doe";
customer.DefaultBillingAddress = new Address();
customer.DefaultBillingAddress.Street = "One Microsoft Way";
customer.DefaultDeliveryAddress = customer.DefaultBillingAddress;
customer.AccountID = 42;
ChannelFactory<ICustomerManager> factory =
new ChannelFactory<ICustomerManager>("customermanager");
ICustomerManager customerManager = factory.CreateChannel();
customerManager.StoreCustomer(customer);
Hizmet, referansla bir nesne döndürür
Bu senaryo için istemci uygulaması uzak hizmete bir çağrı yapar ve yöntem, hizmetten istemciye referans yoluyla geçen bir nesne döndürür.
Daha önce belirtildiği gibi WCF hizmetleri her zaman değere göre nesne döndürür. Ancak, sınıfını EndpointAddress10 kullanarak benzer bir sonuç elde edebilirsiniz. EndpointAddress10 değer tipinde serileştirilebilir bir nesnedir ve istemci tarafından sunucuda oturumlu bir başvuru nesnesi elde etmek için kullanılabilir.
Bu senaryoda gösterilen WCF'deki başvuru nesnesinin davranışı DCOM'dan farklıdır. DCOM'da, sunucu doğrudan istemciye bir başvuru nesnesi döndürebilir ve istemci bu nesnenin sunucuda yürütülen yöntemlerini çağırabilir. Ancak WCF'de döndürülen nesne her zaman değere göredir. İstemci, EndpointAddress10 ile temsil edilen bu değerlere göre nesneyi almalı ve kendi oturumlu başvuru nesnesini oluşturmak için kullanmalıdır. İstemci yöntemi, sunucuda yürütülen oturumlu nesnede çağrılar yapar. Yani, WCF'deki bu başvuru türü nesne, oturumlu olacak şekilde yapılandırılmış normal bir WCF hizmetidir.
WCF'de oturum, iki uç nokta arasında gönderilen birden çok iletiyi ilişkilendirmenin bir yoludur. Bu, bir istemci bu hizmete bir bağlantı edindikten sonra istemci ile sunucu arasında bir oturum kurulacağı anlamına gelir. İstemci, bu tek oturumdaki tüm etkileşimleri için sunucu tarafı nesnesinin tek bir benzersiz örneğini kullanır. Oturumlu WCF sözleşmeleri, bağlantı odaklı ağ isteği/yanıt desenlerine benzer.
Bu senaryo aşağıdaki DCOM yöntemiyle temsil edilir.
public interface IRemoteService
{
IRemoteObject GetObjectByReference();
}
1. Adım: Oturumlu WCF hizmet arabirimini ve uygulamasını tanımlama
İlk olarak, oturumlu nesnesini içeren bir WCF hizmet arabirimi tanımlayın.
Bu kodda, oturumlu nesne, onu normal bir WCF hizmet arabirimi olarak tanımlayan özniteliğiyle ServiceContract işaretlenir. Buna ek olarak, SessionMode özelliği oturumlu bir hizmet olacağını belirtmek için ayarlanır.
[ServiceContract(SessionMode = SessionMode.Allowed)]
public interface ISessionBoundObject
{
[OperationContract]
string GetCurrentValue();
[OperationContract]
void SetCurrentValue(string value);
}
Aşağıdaki kod hizmet uygulamasını gösterir.
Hizmet [ServiceBehavior] özniteliğiyle işaretlenir ve instanceContextMode özelliği InstanceContextMode.PerSessions olarak ayarlanır ve bu türün benzersiz bir örneğinin her oturum için oluşturulması gerektiğini belirtir.
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class MySessionBoundObject : ISessionBoundObject
{
private string _value;
public string GetCurrentValue()
{
return _value;
}
public void SetCurrentValue(string val)
{
_value = val;
}
}
2. Adım: Oturumlu nesne için WCF fabrika hizmetini tanımlama
Oturumlu nesneyi oluşturan hizmet tanımlanmalı ve uygulanmalıdır. Aşağıdaki kod bunun nasıl yapılacağını gösterir. Bu kod, bir EndpointAddress10 nesnesi döndüren başka bir WCF hizmeti oluşturur. Bu, oturumun tam nesnesini oluşturmak için kullanabileceği bir uç noktanın serileştirilebilir bir biçimidir.
[ServiceContract]
public interface ISessionBoundFactory
{
[OperationContract]
EndpointAddress10 GetInstanceAddress();
}
Aşağıda bu hizmetin uygulanması yer alır. Bu uygulama, oturumlu nesneler oluşturmak için singleton kanal fabrikasını yönetir. Çağrıldığında GetInstanceAddress , bir kanal oluşturur ve bu kanalla ilişkilendirilmiş uzak adrese işaret eden bir EndpointAddress10 nesne oluşturur.
EndpointAddress10 , istemciye değere göre döndürülebilen bir veri türüdür.
public class SessionBoundFactory : ISessionBoundFactory
{
public static ChannelFactory<ISessionBoundObject> _factory =
new ChannelFactory<ISessionBoundObject>("sessionbound");
public SessionBoundFactory()
{
}
public EndpointAddress10 GetInstanceAddress()
{
IClientChannel channel = (IClientChannel)_factory.CreateChannel();
return EndpointAddress10.FromEndpointAddress(channel.RemoteAddress);
}
}
3. Adım: WCF hizmetlerini yapılandırma ve başlatma
Bu hizmetleri barındırmak için sunucunun yapılandırma dosyasına (web.config) aşağıdaki eklemeleri yapmanız gerekir.
Oturumlu nesnenin uç noktasını açıklayan bir
<client>bölüm ekleyin. Bu senaryoda, sunucu aynı zamanda bir istemci işlevi görür ve bunu etkinleştirmek için yapılandırılması gerekir.<services>bölümünde, fabrika ve oturumlu nesne için hizmet uç noktalarını bildirin. Bu, istemcinin hizmet uç noktalarıyla iletişim kurmasını, EndpointAddress10 oturumlu kanalı oluşturmasını ve edinmesini sağlar.
Aşağıda, bu ayarlara sahip örnek bir yapılandırma dosyası verilmiştir:
<configuration>
<system.serviceModel>
<client>
<endpoint name="sessionbound"
address="net.tcp://localhost:8081/SessionBoundObject"
binding="netTcpBinding"
contract="Shared.ISessionBoundObject"/>
</client>
<services>
<service name="Server.MySessionBoundObject">
<endpoint address="net.tcp://localhost:8081/SessionBoundObject"
binding="netTcpBinding"
contract="Shared.ISessionBoundObject" />
</service>
<service name="Server.SessionBoundFactory">
<endpoint address="net.tcp://localhost:8081/SessionBoundFactory"
binding="netTcpBinding"
contract="Shared.ISessionBoundFactory" />
</service>
</services>
</system.serviceModel>
</configuration>
Hizmeti kendi kendine barındırmak ve uygulamayı başlatmak için bir konsol uygulamasına aşağıdaki satırları ekleyin.
ServiceHost factoryHost = new ServiceHost(typeof(SessionBoundFactory));
factoryHost.Open();
ServiceHost sessionBoundServiceHost = new ServiceHost(
typeof(MySessionBoundObject));
sessionBoundServiceHost.Open();
4. Adım: İstemciyi yapılandırma ve hizmeti çağırma
Projenin uygulama yapılandırma dosyasında (app.config) aşağıdaki girişleri yaparak istemciyi WCF hizmetleriyle iletişim kuracak şekilde yapılandırın.
<configuration>
<system.serviceModel>
<client>
<endpoint name="sessionbound"
address="net.tcp://localhost:8081/SessionBoundObject"
binding="netTcpBinding"
contract="Shared.ISessionBoundObject"/>
<endpoint name="factory"
address="net.tcp://localhost:8081/SessionBoundFactory"
binding="netTcpBinding"
contract="Shared.ISessionBoundFactory"/>
</client>
</system.serviceModel>
</configuration>
Hizmeti çağırmak için, aşağıdakileri yapmak için istemciye kodu ekleyin:
ISessionBoundFactoryhizmetine bir kanal oluşturun.Kanalı kullanarak
ISessionBoundFactoryhizmetini çağırın ve bir EndpointAddress10 nesnesi alın.Bir oturumlu nesne elde etmek için bir kanal oluşturmak amacıyla EndpointAddress10 öğesini kullanın.
SetCurrentValueveGetCurrentValueyöntemlerini çağırarak aynı nesne örneğinin birden çok çağrıda aynı kaldığını gösterin.
ChannelFactory<ISessionBoundFactory> factory =
new ChannelFactory<ISessionBoundFactory>("factory");
ISessionBoundFactory sessionBoundFactory = factory.CreateChannel();
EndpointAddress10 address = sessionBoundFactory.GetInstanceAddress();
ChannelFactory<ISessionBoundObject> sessionBoundObjectFactory =
new ChannelFactory<ISessionBoundObject>(
new NetTcpBinding(),
address.ToEndpointAddress());
ISessionBoundObject sessionBoundObject =
sessionBoundObjectFactory.CreateChannel();
sessionBoundObject.SetCurrentValue("Hello");
if (sessionBoundObject.GetCurrentValue() == "Hello")
{
Console.WriteLine("Session-full instance management works as expected");
}