Özel Hizmet Sunucusu

CustomServiceHost örneği, bir hizmetin çalışma zamanı davranışını değiştirmek için sınıfının özel bir türevinin ServiceHost nasıl kullanılacağını gösterir. Bu yaklaşım, çok sayıda hizmeti ortak bir şekilde yapılandırmaya yeniden kullanılabilir bir alternatif sağlar. Örnek ayrıca, Internet Information Services (IIS) veya Windows İşlem Etkinleştirme Hizmeti (WAS) barındırma ortamında özel bir ServiceHost kullanmak için sınıfının nasıl ServiceHostFactory kullanılacağını gösterir.

Senaryo hakkında

Hassas olabilecek hizmet meta verilerinin yanlışlıkla açıklanmasını önlemek için, Windows Communication Foundation (WCF) hizmetleri için varsayılan yapılandırma meta veri yayımlamayı devre dışı bırakır. Bu davranış varsayılan olarak güvenlidir, ancak aynı zamanda hizmetin meta veri yayımlama davranışı yapılandırmada açıkça etkinleştirilmediği sürece hizmeti çağırmak için gereken istemci kodunu oluşturmak için bir meta veri içeri aktarma aracı (Svcutil.exegibi) kullanamazsınız.

Çok sayıda hizmet için meta veri yayımlamayı etkinleştirmek için her bir hizmete aynı yapılandırma öğelerinin eklenmesi gerekir ve bu da temelde aynı olan büyük miktarda yapılandırma bilgisi elde edilmesini sağlar. Her hizmeti ayrı ayrı yapılandırmaya alternatif olarak, meta veri yayımlamayı bir kez etkinleştiren kesinlik temelli kodu yazmak ve ardından bu kodu birkaç farklı hizmette yeniden kullanmak mümkündür. Bu, ServiceHost sınıfından türeyen ve ApplyConfiguration() yöntemini geçirimsiz bir şekilde meta veri yayımlama davranışını eklemek için geçersiz kılan yeni bir sınıf oluşturarak gerçekleştirilir.

Önemli

Netlik sağlamak için bu örnekte güvenli olmayan meta veri yayımlama uç noktasının nasıl oluşturulacağı gösterilmektedir. Bu tür uç noktalar anonim kimliği doğrulanmamış tüketiciler tarafından kullanılabilir ve hizmetin meta verilerini genel olarak açıklamanın uygun olduğundan emin olmak için bu uç noktalar dağıtılmadan önce dikkatli olunmalıdır.

Özel bir ServiceHost Gerçekleştirme

sınıfı, ServiceHost devralanların bir hizmetin çalışma zamanı davranışını değiştirmek için geçersiz kabileceği birkaç yararlı sanal yöntemi kullanıma sunar. Örneğin, ApplyConfiguration() yöntemi yapılandırma deposundan hizmet yapılandırma bilgilerini okur ve konağın ServiceDescription bilgilerini buna göre değiştirir. Varsayılan uygulama, uygulamanın yapılandırma dosyasından yapılandırmayı okur. Özel uygulamalar, emredici kod kullanarak ApplyConfiguration üzerinde daha fazla değişiklik yapmak veya varsayılan yapılandırma deposunu tamamen değiştirmek için ServiceDescription() geçersiz kılabilir. Örneğin, uygulamanın yapılandırma dosyası yerine bir veritabanından hizmetin uç nokta yapılandırmasını okumak için.

Bu örnekte, bu davranış hizmetin yapılandırma dosyasına açıkça eklenmese bile ServiceMetadataBehavior'ı (meta veri yayımlamayı etkinleştirir) ekleyen özel bir ServiceHost oluşturmak istiyoruz. Bunu başarmak için, öğesinden ServiceHost türetilen ve ApplyConfiguration() yöntemini geçersiz kılan yeni bir sınıf oluşturun.

class SelfDescribingServiceHost : ServiceHost
{
    public SelfDescribingServiceHost(Type serviceType, params Uri[] baseAddresses)
        : base(serviceType, baseAddresses) { }

    //Overriding ApplyConfiguration() allows us to
    //alter the ServiceDescription prior to opening
    //the service host.
    protected override void ApplyConfiguration()
    {
        //First, we call base.ApplyConfiguration()
        //to read any configuration that was provided for
        //the service we're hosting. After this call,
        //this.Description describes the service
        //as it was configured.
        base.ApplyConfiguration();

        //(rest of implementation elided for clarity)
    }
}

Uygulamanın yapılandırma dosyasında sağlanan herhangi bir yapılandırmayı göz ardı etmek istemediğimiz için, ApplyConfiguration yöntemimizi geçersiz kıldığımızda yaptığımız ilk şey temel uygulamayı çağırmaktır. Bu yöntem tamamlandığında, aşağıdaki zorunlu kodu kullanarak tanıma ServiceMetadataBehavior ekleyebiliriz.

ServiceMetadataBehavior mexBehavior = this.Description.Behaviors.Find<ServiceMetadataBehavior>();
if (mexBehavior == null)
{
    mexBehavior = new ServiceMetadataBehavior();
    this.Description.Behaviors.Add(mexBehavior);
}
else
{
    //Metadata behavior has already been configured,
    //so we do not have any work to do.
    return;
}

() geçersiz kılmamızın ApplyConfigurationyapması gereken son şey, varsayılan meta veri uç noktasını eklemektir. Kural gereği, hizmet ana bilgisayarının BaseAddresses koleksiyonundaki her URI için bir meta veri uç noktası oluşturulur.

//Add a metadata endpoint at each base address
//using the "/mex" addressing convention
foreach (Uri baseAddress in this.BaseAddresses)
{
    if (baseAddress.Scheme == Uri.UriSchemeHttp)
    {
        mexBehavior.HttpGetEnabled = true;
        this.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName,
                                MetadataExchangeBindings.CreateMexHttpBinding(),
                                "mex");
    }
    else if (baseAddress.Scheme == Uri.UriSchemeHttps)
    {
        mexBehavior.HttpsGetEnabled = true;
        this.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName,
                                MetadataExchangeBindings.CreateMexHttpsBinding(),
                                "mex");
    }
    else if (baseAddress.Scheme == Uri.UriSchemeNetPipe)
    {
        this.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName,
                                MetadataExchangeBindings.CreateMexNamedPipeBinding(),
                                "mex");
    }
    else if (baseAddress.Scheme == Uri.UriSchemeNetTcp)
    {
        this.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName,
                                MetadataExchangeBindings.CreateMexTcpBinding(),
                                "mex");
    }
}

Kendi kendine barındırmada özel ServiceHost kullanma

Özel ServiceHost uygulamamızı tamamladığımıza göre, artık bu servisimizi SelfDescribingServiceHost örneği içinde barındırarak herhangi bir servise meta veri yayınlama özelliği ekleyebiliriz. Aşağıdaki kod, kendi kendine barındırma senaryosunda nasıl kullanılacağını gösterir.

SelfDescribingServiceHost host =
         new SelfDescribingServiceHost( typeof( Calculator ) );
host.Open();

Özel ana bilgisayarımız, hizmeti barındırmak için varsayılan ServiceHost sınıfı kullanmışız gibi uygulamanın yapılandırma dosyasından hizmetin uç nokta yapılandırmasını okumaya devam eder. Ancak, özel ana bilgisayarımızda meta veri yayımlamayı etkinleştirmek için mantığı eklediğimizden, artık yapılandırmada meta veri yayımlama davranışını açıkça etkinleştirmemiz gerekmez. Çeşitli hizmetler içeren bir uygulama oluştururken ve aynı yapılandırma öğelerini tekrar tekrar yazmadan her birinde meta veri yayımlamayı etkinleştirmek istediğinizde bu yaklaşımın ayrı bir avantajı vardır.

IIS veya WAS'de özel ServiceHost kullanma

Özel bir hizmet konağı kullanmak, kendi kendine konak senaryolarında basittir, çünkü hizmet ana bilgisayar örneğini oluşturmak ve açmakla esas olarak sizin uygulama kodunuz sorumludur. Ancak IIS veya WAS barındırma ortamında WCF altyapısı, gelen iletilere yanıt olarak hizmetinizin ana bilgisayar örneğini dinamik olarak oluşturur. Özel hizmet konakları bu barındırma ortamında da kullanılabilir, ancak ServiceHostFactory biçiminde bazı ek kodlar gerektirir. Aşağıdaki kod, bizim özel ServiceHostFactory örneklerimizi döndüren SelfDescribingServiceHost türevini gösterir.

public class SelfDescribingServiceHostFactory : ServiceHostFactory
{
    protected override ServiceHost CreateServiceHost(Type serviceType,
     Uri[] baseAddresses)
    {
        //All the custom factory does is return a new instance
        //of our custom host class. The bulk of the custom logic should
        //live in the custom host (as opposed to the factory)
        //for maximum
        //reuse value outside of the IIS/WAS hosting environment.
        return new SelfDescribingServiceHost(serviceType,
                                             baseAddresses);
    }
}

Gördüğünüz gibi, özel bir ServiceHostFactory uygulamak basittir. Özel mantığın tümü ServiceHost uygulamasının içinde bulunur; fabrika türetilmiş sınıfın bir örneğini döndürür.

Bir hizmet uygulamasıyla özel fabrika kullanmak için hizmetin .svc dosyasına bazı ek meta veriler eklemeliyiz.

<% @ServiceHost Service="Microsoft.ServiceModel.Samples.CalculatorService"
               Factory="Microsoft.ServiceModel.Samples.SelfDescribingServiceHostFactory"
               language=c# Debug="true" %>

Burada Factory öznitelik olarak özel fabrikamızın CLR tür adını geçirdik ve @ServiceHost yönergesine ek bir öznitelik ekledik. IIS veya WAS bu hizmet için bir ileti aldığında, WCF barındırma altyapısı önce ServiceHostFactory'nin bir örneğini oluşturur ve ardından ServiceHostFactory.CreateServiceHost()'i çağırarak hizmet ana bilgisayarını başlatır.

Örneği çalıştırma

Bu örnek, istemci ve hizmetin tam işlevsel bir uygulamasını sağlasa da, amaç, bir hizmetin çalışma zamanı davranışını özelleştirilmiş bir konak aracılığıyla nasıl değiştirebileceğimizi göstermektir. Aşağıdaki adımları uygulayın:

Özel ana bilgisayarın etkisini gözlemleyin

  1. Hizmetin Web.config dosyasını açın ve hizmet için meta verileri açıkça etkinleştiren bir yapılandırma olmadığını gözlemleyin.

  2. Hizmetin .svc dosyasını açın ve yönergesinin @ServiceHost özel bir ServiceHostFactory'nin adını belirten bir Factory özniteliği içerdiğini gözlemleyin.

Örneği ayarlama, derleme ve çalıştırma

  1. Windows Communication Foundation Örnekleri içinOne-Time Kurulum Yordamını yaptığınızdan emin olun.

  2. Çözümü oluşturmak için Windows Communication Foundation Örnekleri Oluşturma başlığındaki yönergeleri izleyin.

  3. Çözüm oluşturulduktan sonra Setup.bat çalıştırarak IIS 7.0'da ServiceModelSamples Uygulamasını ayarlayın. ServiceModelSamples dizini artık iis 7.0 uygulaması olarak görünmelidir.

  4. Örneği tek bir makine veya makineler arası bir yapılandırmada çalıştırmak için, Windows Communication Foundation örneklerini çalıştırmayönergelerini izleyin.

  5. IIS 7.0 uygulamasını kaldırmak için Cleanup.batçalıştırın.

Ayrıca bakınız