Sdílet prostřednictvím


Úvod vývojáře do Windows Communication Foundation 4

Aaron Skonnard, Pluralsight

Původní: listopad 2009

Aktualizováno na RTM: duben 2010

Přehled

.NET 4 obsahuje některé zajímavé nové funkce a vítá vylepšení v oblasti Windows Communication Foundation (WCF). Tato vylepšení WCF se zaměřují především na zjednodušení vývojářského prostředí, umožnění více komunikačních scénářů a zajištění bohaté integrace se službou Windows Workflow Foundation (WF) tím, že "služby pracovních postupů" se posunou vpřed.

Dobrou zprávou je většina změn WCF 4, které se zaměřují na usnadnění dnešních běžných scénářů a vytváření nových komunikačních scénářů a stylů vývoje. V důsledku toho bude přesun stávajících řešení WCF na .NET 4 poměrně bezproblémový z hlediska migrace. Pak se jednoduše rozhodnete, které funkce WCF 4 chcete v řešeních využít. Zbytek tohoto dokumentu vás seznámí s každou z nových oblastí funkcí WCF 4 a předvádí, jak fungují.

Novinky ve WCF 4

WCF 4 obsahuje širokou škálu konkrétních funkcí, ale obrázek 1 popisuje hlavní oblasti funkcí, na které se zaměříme v následujícím dokumentu. Tyto oblasti funkcí shrnují většinu novinek ve WCF 4 a zvýrazňují příležitosti nejvyšší úrovně, které nabízí tato verze rozhraní .NET Framework.

obrázek 1: Oblasti funkcí WCF 4

Oblast funkcí Popis

Zjednodušená konfigurace

Zjednodušení oddílu konfigurace WCF prostřednictvím podpory výchozích koncových bodů, vazeb a chování konfigurace. Tyto změny umožňují hostovat služby bez konfigurace, což výrazně zjednodušuje vývojářské prostředí pro nejběžnější scénáře WCF.

Objev

Nová podpora rozhraní pro chování ad hoc i zjišťování spravovaných služeb, které odpovídají standardnímu protokolu WS-Discovery.

Směrovací služba

Nová podpora architektury pro konfigurovatelnou směrovací službu, kterou můžete použít ve svých řešeních WCF. Poskytuje funkce pro směrování založené na obsahu, přemostění protokolu a zpracování chyb.

Vylepšení REST

Vylepšení služeb WCF WebHttp s některými dalšími funkcemi a nástroji, které zjednodušují vývoj služeb REST.

Služby pracovních postupů

Bohatá podpora architektury pro integraci WCF s WF pro implementaci deklarativních dlouhotrvajících služeb pracovních postupů Tento nový programovací model poskytuje nejlepší obě architektury, které musí nabídnout (WCF & WF).

Jakmile dokončíme pokrytí těchto hlavních oblastí funkcí, stručně probereme některé pokročilejší funkce WCF nižší úrovně, které jsou součástí .NET 4, včetně věcí, jako jsou vylepšené možnosti řešení typů, podpora front s konkurenčními spotřebiteli ("příjem kontextu"), podporu pro nezapsaná binární data prostřednictvím kodéru bajtů streamu a podpora vysoce výkonného trasování založeného na trasování etW.

Po dokončení uvidíte, že se wcf 4 snadněji používá a poskytuje více integrovanou podporu některých dnešních nejběžnějších scénářů a stylů vývoje.

Zjednodušená konfigurace

Jednotný programovací model nabízený WCF ve verzi 3.x je požehnáním i prokletím – zjednodušuje psaní logiky služby pro různé komunikační scénáře, ale také zvyšuje složitost na straně konfigurace, protože poskytuje tolik různých základních komunikačních možností, které jste nuceni pochopit, než začnete.

Realita je konfigurace WCF obvykle stává nákladnější oblastí použití WCF v praxi v současné době a velká část této složitosti se nachází na IT/provozním personálu, kteří jsou nepřipravení k jeho řešení.

Vzhledem k této realitě, když uvažujete o čisté složitosti používání WCF 3.x, může být důvodně závěr, že je obtížnější použít než jeho předchůdce ASP.NET webových služeb (ASMX). S ASMX jste mohli definovat operaci [WebMethod] a modul runtime automaticky poskytl výchozí konfiguraci pro podkladovou komunikaci. Při přechodu na WCF 3.x naopak vývojáři musí vědět dostatek informací o různých možnostech konfigurace WCF, aby definovali aspoň jeden koncový bod. A strašidelný počet možností konfigurace často vyděsí některé vývojáře pryč.

Ve snaze zajistit, aby bylo celkové prostředí WCF stejně snadné jako ASMX, wcf 4 obsahuje nový "výchozí konfigurace" model, který zcela eliminuje potřebu jakékoli konfigurace WCF. Pokud pro konkrétní službu nezadáte žádnou konfiguraci WCF, modul runtime WCF 4 automaticky nakonfiguruje vaši službu s některými standardními koncovými body a výchozí konfigurací vazby a chování. To usnadňuje zprovoznění služby WCF, zejména pro ty, kteří nejsou obeznámeni s různými možnostmi konfigurace WCF a jsou rádi, že přijmou výchozí hodnoty, aspoň abyste mohli začít.

Výchozí koncové body

Pokud se ve WCF 3.x pokusíte hostovat službu bez nakonfigurovaných koncových bodů, instance ServiceHost vyvolá výjimku s informací, že je potřeba nakonfigurovat aspoň jeden koncový bod. U WCF 4 už to neplatí, protože modul runtime za vás automaticky přidá jeden nebo více "výchozích koncových bodů", takže bude služba použitelná bez jakékoli konfigurace.

Tady je postup, jak to funguje. Když hostitelská aplikace volá Open v instanci ServiceHost, sestaví interní popis služby z konfiguračního souboru aplikace spolu s tím, co hostitelské aplikace může explicitně nakonfigurovat a pokud je počet nakonfigurovaných koncových bodů stále nulový, volá AddDefaultEndpoints, novou veřejnou metodu nalezenou ve třídě ServiceHost. Tato metoda přidá jeden nebo více koncových bodů do popisu služby na základě základních adres služby (ve scénářích služby IIS se jedná o adresu .svc). Vzhledem k tomu, že je metoda veřejná, můžete ji také volat přímo ve vlastních scénářích hostování.

Aby byla přesnost, implementace AddDefaultEndpoints přidá jeden výchozí koncový bod na základní adresu pro každý kontrakt služby implementovaný službou. Pokud například služba implementuje dva kontrakty služeb a vy nakonfigurujete hostitele s jednou základní adresou, AddDefaultEndpoints nakonfiguruje službu se dvěma výchozími koncovými body (jeden pro každý kontrakt služby). Pokud ale služba implementuje dva kontrakty služeb a hostitel je nakonfigurovaný se dvěma základními adresami (jeden pro HTTP a jeden pro TCP), AddDefaultEndpoints nakonfiguruje službu se čtyřmi výchozími koncovými body.

Pojďme se podívat na úplný příklad, který znázorňuje, jak to funguje. Předpokládejme, že máte následující kontrakty služeb WCF a následující implementaci služby:

[ServiceContract]

veřejné rozhraní IHello

{

    [OperationContract]

    void SayHello(název řetězce);

}

[ServiceContract]

veřejné rozhraní IGoodbye

{

    [OperationContract]

    void SayGoodbye(název řetězce);

}

public class GreetingService : IHello, IGoodbye // služba implementuje oba kontrakty

{

    public void SayHello(název řetězce)

    {

        Console.WriteLine("Hello {0}"; name);

    }

    public void SayGoodbye(název řetězce)

    {

        Console.WriteLine("Goodbye {0}"; name);

    }

}

Pomocí WCF 4 teď můžete serviceHost použít k hostování služby GreetingService bez jakékoli konfigurace aplikace. Pokud používáte ServiceHost ve vlastních scénářích hostování, budete muset zadat jednu nebo více základních adres, které se mají použít. Následující příklad ukazuje, jak hostovat službu GreetingService v konzolové aplikaci a znovu můžete předpokládat, že neexistuje žádný app.config soubor přidružený k tomuto programu:

program třídy

{

    static void Main(string[] args)

    {

        Hostitel je nakonfigurovaný se dvěma základními adresami, jednou pro HTTP a druhou pro TCP.

        Hostitel ServiceHost = new ServiceHost(typeof(GreetingService),

            new Uri("https://localhost:8080/greeting");

            new Uri("net.tcp://localhost:8081/greeting"));

        hostitel. Open();

        foreach (ServiceEndpoint se v hostiteli. Description.Endpoints)

            Console.WriteLine("A: {0}, B: {1}, C: {2}",

                se. Adresa, se.Binding.Name, se.Contract.Name);

        Console.WriteLine("Stisknutím klávesy <Enter> službu zastavíte.");

        Console.ReadLine();

        hostitel. Close();

    }

}

Tento příklad nakonfiguruje ServiceHost se dvěma základními adresami: jednu pro HTTP a druhou pro TCP. Při spuštění tohoto programu uvidíte čtyři koncové body vytištěné do okna konzoly, jak je znázorněno na obrázku 2. Získáte dva pro základní adresu HTTP, jednu na kontrakt a dvě pro základní adresu TCP, a to znovu jeden na kontrakt. To vše poskytuje na pozadí instance ServiceHost.

Obrázek 2: Výchozí koncové body zobrazené v okně konzoly

Všimněte si, jak se WCF rozhodne použít BasicHttpBinding pro výchozí koncové body HTTP a NetTcpBinding pro výchozí koncové body TCP. Krátce vám ukážu, jak tyto výchozí hodnoty změnit.

Mějte na paměti, že toto výchozí chování koncového bodu se spustí jenom v případě, že služba nebyla nakonfigurována s žádnými koncovými body. Pokud změním konzolovou aplikaci tak, aby službu nakonfigurovali alespoň s jedním koncovým bodem, ve výstupu se už nezobrazí žádné z těchto výchozích koncových bodů. Abychom to mohli ilustrovat, jednoduše přidám následující řádek kódu, který volá AddServiceEndpoint po vytvoření instance ServiceHost:

...

Hostitel ServiceHost = new ServiceHost(typeof(GreetingService),

    new Uri("https://localhost:8080/greeting");

    new Uri("net.tcp://localhost:8081/greeting"));

hostitel. AddServiceEndpoint(typeof(IHello), nový WSHttpBinding(), "myendpoint");

...

Pokud spustíte konzolovou aplikaci s vloženým řádkem kódu, uvidíte, že ve výstupu se teď zobrazí jenom jeden koncový bod – ten, který jsme nakonfigurovali ručně v kódu výše (viz obrázek 3).

Obrázek 3: Výstup konzoly po konfiguraci hostitele s jedním koncovým bodem

Pokud ale chcete přidat sadu výchozích koncových bodů spolu s vlastními koncovými body, můžete vždy volat addDefaultEndpoints sami. Následující příklad kódu ukazuje, jak to udělat:

...

Hostitel ServiceHost = new ServiceHost(typeof(GreetingService),

    new Uri("https://localhost:8080/greeting");

    new Uri("net.tcp://localhost:8081/greeting"));

hostitel. AddServiceEndpoint(typeof(IHello), nový WSHttpBinding(), "myendpoint");

hostitel. AddDefaultEndpoints();

...

Pokud znovu spustíte konzolovou aplikaci s touto změnou, zobrazí se v okně konzoly pět koncových bodů – jeden, který jsem nakonfiguroval ručně spolu se čtyřmi výchozími koncovými body (viz obrázek 4).

Obrázek 4: Výstup konzoly po ručním volání addDefaultEndpoints

Když teď chápeme algoritmus a mechaniku pro přidání výchozích koncových bodů do služeb za běhu, je další otázkou, jak WCF rozhodne, kterou vazbu použít pro konkrétní založenou adresu?

Výchozí mapování protokolu

Odpověď na tuto otázku je jednoduchá. WCF definuje výchozí mapování protokolu mezi schématy přenosového protokolu (např. http, net.tcp, net.pipe atd.) a integrovanými vazbami WCF. Výchozí mapování protokolu se nachází v souboru .NET 4 machine.config.comments a vypadá takto:

<system.serviceModel>

   <protocolMapping>

      <add scheme="http" binding="basicHttpBinding" bindingConfiguration="" />

      <add scheme="net.tcp" binding="netTcpBinding" bindingConfiguration="/>

      <add scheme="net.pipe" binding="netNamedPipeBinding" bindingConfiguration="/>

      <add scheme="net.msmq" binding="netMsmqBinding" bindingConfiguration="/>

   </protocolMapping>

   ...

Tato mapování můžete přepsat na úrovni počítače přidáním této části do machine.config a úpravou mapování pro každé schéma protokolu. Nebo pokud ho chcete přepsat jenom v rámci oboru aplikace, můžete tuto část v konfiguračním souboru aplikace nebo webu přepsat.

Pokud se například vaše organizace zaměřuje především na vytváření služeb RESTful pomocí WCF, může být vhodné změnit výchozí vazbu schématu protokolu HTTP na WebHttpBinding. Následující příklad ukazuje, jak toho dosáhnout v rámci konfiguračního souboru aplikace:

> konfigurace <

  <system.serviceModel>

    <protocolMapping>

      <add scheme="http" binding="webHttpBinding"/>

    </protocolMapping>

  </system.serviceModel>

</configuration>

Když teď znovu spustím konzolovou aplikaci zobrazenou dříve s touto app.config, zobrazí se u dvou výchozích koncových bodů založených na protokolu HTTP, které používají webHttpBinding (viz obrázek 5).

Obrázek 5: Výstup konzoly po přepsání výchozího mapování protokolu HTTP

Jakmile WCF určí, kterou vazbu použít prostřednictvím tabulky mapování protokolu, použije při konfiguraci výchozího koncového bodu výchozí konfiguraci vazby. Pokud s integrovanými výchozími nastaveními vazeb nejste spokojení, můžete také přepsat výchozí konfiguraci konkrétní vazby.

Výchozí konfigurace vazeb

Každá vazba WCF obsahuje výchozí konfiguraci, která se používá, pokud ji hostitelská aplikace explicitně nepřepíše pro konkrétní koncový bod. Každá instance vazby, kterou použijete, má vždy předdefinované výchozí hodnoty, pokud se nerozhodnete přepsat použitím explicitní konfigurace vazby.

V WCF 3.x to provedete definováním pojmenované konfigurace vazby, kterou můžete použít u definic koncových bodů prostřednictvím atributu bindingConfiguration. Mechanismus toho, jak to správně udělat, je těžkopádný a náchylný k chybám.  Následující konfigurační soubor ukazuje typický příklad:

> konfigurace <

  <system.serviceModel>

    vazby <>

      <basicHttpBinding>

        <binding name="BasicWithMtom" messageEncoding="Mtom"/>

      </basicHttpBinding>

    </bindings>

    > služeb <

      <service name="GreetingService">

        <endpoint address="mtom" binding="basicHttpBinding"

                  bindingConfiguration="BasicWithMtom"

                  contract="IHello"/>

      </service>

    </services>

  </system.serviceModel>

</configuration>

V předchozím příkladu přepíše konfigurace vazby BasicWithMtom výchozí hodnoty pro BasicHttpBinding změnou kódování zprávy na MTOM. Tato konfigurace vazby se ale projeví jenom v případě, že ji použijete na konkrétní koncový bod prostřednictvím atributu bindingConfiguration – jedná se o krok, který často vyvolává problémy s konfigurací vývojářů a provozních pracovníků.

Pomocí WCF 4 teď můžete definovat výchozí konfigurace vazeb tak, že při definování nové konfigurace jednoduše vynecháte název konfigurace vazby. Wcf pak použije tuto výchozí konfiguraci pro všechny koncové body pomocí této vazby, které nemají nastavenou explicitní konfiguraci vazby.

Pokud například do konzolové aplikace zobrazené výše přidáme následující app.config soubor, vyberou tyto dva výchozí koncové body HTTP tuto výchozí konfiguraci BasicHttpBinding, která umožňuje MTOM:

> konfigurace <

  <system.serviceModel>

    vazby <>

      <basicHttpBinding>

        <vazby messageEncoding="Mtom"/><!-- si všimněte, že neexistuje žádný atribut názvu –>

      </basicHttpBinding>

    </bindings>

  </system.serviceModel>

</configuration>

Tyto výchozí konfigurace vazeb můžete samozřejmě přidat také do machine.config, pokud chcete, aby se projevily ve všech službách spuštěných na počítači, nebo je můžete definovat v aplikaci podle aplikace přidáním výchozích konfigurací vazeb v konfiguračním souboru aplikace.

Tato funkce poskytuje jednoduchý mechanismus pro definování standardní sady výchozích vazeb, které můžete používat ve všech službách, aniž byste museli ukládat složitost konfigurací vazeb jiným vývojářům nebo pracovníkům IT/provozu. Můžou jednoduše zvolit příslušnou vazbu a ujistit se, že hostitelské prostředí poskytne správnou výchozí konfiguraci.

Kromě výchozích konfigurací vazeb je další věcí, kterou je potřeba zvážit pro vaše služby a koncové body, to, co by měla být jejich výchozí konfigurace chování.

Výchozí konfigurace chování

WCF 4 také umožňuje definovat výchozí konfigurace chování pro služby a koncové body, což může zjednodušit, když chcete sdílet standardní výchozí konfiguraci chování napříč všemi službami nebo koncovými body běžícími na počítači nebo v rámci řešení.

Ve WCF 3.x musíte definovat pojmenované konfigurace chování, které explicitně použijete u služeb a koncových bodů prostřednictvím atributu behaviorConfiguration. Pomocí WCF 4 můžete definovat výchozí konfigurace chování tak, že v definici konfigurace vynecháte název. Pokud tyto výchozí chování přidáte do machine.config, budou platit pro všechny služby nebo koncové body hostované na počítači. Pokud je přidáte do app.config, projeví se pouze v rámci hostitelské aplikace. Tady je příklad:

> konfigurace <

  <system.serviceModel>

    <chování>

      <serviceBehaviors>

        <chování><!-- nevšimne žádný atribut názvu –>

          <serviceMetadata httpGetEnabled="true"/>

        </behavior>

       </serviceBehaviors>

    </behaviors>

  </system.serviceModel>

</configuration>

Tento příklad zapne metadata služby pro všechny služby, které nejsou součástí explicitní konfigurace chování. Pokud přidáme tuto výchozí konfiguraci chování do souboru app.config pro konzolovou aplikaci se zobrazí dříve a spustíme aplikaci znovu, můžeme přejít na základní adresu HTTP a načíst stránku nápovědy služby a definici WSDL služby (viz obrázek 6).

Obrázek 6: Přechod na metadata služby povolená ve výchozím nastavení konfigurace chování

Další novou funkcí WCF 4 je, že konfigurace chování teď podporují model dědičnosti. Pokud aplikace definuje konfiguraci chování pomocí stejného názvu, který už je definovaný v machine.config, konfigurace chování specifická pro aplikaci se sloučí s konfigurací celého počítače a přidá další chování do odvozené konfigurace složeného chování.

Standardní koncové body

Souvisí s výchozími koncovými body je další nová funkce WCF 4, která se označuje jako "standardní koncové body". Standardní koncový bod si můžete představit jako běžnou předkonfigurovanou definici koncového bodu integrovanou do architektury WCF 4, kterou můžete jednoduše použít. Standardní koncové body definují "standardní" konfiguraci koncového bodu, kterou obvykle neměníte, i když pokud potřebujete, jak uvidíte krátce.

Obrázek 7 popisuje standardní koncové body, které se dodávají se službou WCF 4. Ty poskytují standardní definice koncových bodů pro některé z nejběžnějších funkcí WCF 4 a komunikačních scénářů. Například v případě koncového bodu MEX budete vždy muset zadat IMetadataExchange pro kontrakt služby a s největší pravděpodobností zvolíte HTTP. Takže místo toho, abyste to vždy vynutili ručně, wcf poskytuje standardní definici koncového bodu pro výměnu metdata s názvem "mexEndpoint", která se snadno používá.

Obrázek 7: Standardní koncové body v WCF 4

Název standardního koncového bodu Popis

mexEndpoint

Definuje standardní koncový bod pro MEX nakonfigurovaný pomocí IMetadataExchange pro kontrakt služby, mexHttpBinding jako výchozí vazbu (můžete to změnit) a prázdnou adresu.

dynamicEndpoint

Definuje standardní koncový bod nakonfigurovaný tak, aby používal zjišťování WCF v rámci klientské aplikace WCF. Při použití tohoto standardního koncového bodu se adresa nevyžaduje, protože během prvního volání se klient dotazuje na koncový bod služby odpovídající zadanému kontraktu a automaticky se k němu za vás připojí. Ve výchozím nastavení se dotaz zjišťování odesílá přes udp vícesměrového vysílání, ale můžete zadat vazbu zjišťování a kritéria hledání, která se mají použít, když potřebujete.

discoveryEndpoint

Definuje standardní koncový bod, který je předem nakonfigurovaný pro operace zjišťování v rámci klientské aplikace. Uživatel musí zadat adresu a vazbu při použití tohoto standardního koncového bodu.

udpDiscoveryEndpoint

Definuje standardní koncový bod, který je předem nakonfigurovaný pro operace zjišťování v rámci klientské aplikace pomocí vazby UDP na adrese vícesměrového vysílání. Odvozuje z DiscoveryEndpointu.

announcementEndpoint

Definuje standardní koncový bod, který je předem nakonfigurovaný pro funkci oznámení zjišťování. Uživatel musí zadat adresu a vazbu při použití tohoto standardního koncového bodu.

udpAnnouncementEndpoint

Definuje standardní koncový bod, který je předem nakonfigurovaný pro funkci oznámení přes vazbu UDP na adrese vícesměrového vysílání. Tento koncový bod je odvozen od oznámeníEndpointu.

workflowControlEndpoint

Definuje standardní koncový bod pro řízení provádění instancí pracovního postupu (vytvoření, spuštění, pozastavení, ukončení atd.).

webHttpEndpoint

Definuje standardní koncový bod nakonfigurovaný pomocí WebHttpBinding a WebHttpBehavior. Slouží k zveřejnění služeb REST.

webScriptEndpoint

Definuje standardní koncový bod nakonfigurovaný pomocí WebHttpBinding a WebScriptEnablingBehavior. Umožňuje zveřejnit služby Ajax.

Libovolný z těchto standardních koncových bodů můžete využít ve vlastních konfiguracích služeb jednoduše tak, že na ně jednoduše odkazujete podle názvu. Prvek <koncového bodu> teď obsahuje atribut "kind", který můžete použít k zadání názvu standardního koncového bodu. Například následující příklad nakonfiguruje službu GreetingService s koncovým bodem MEX pomocí standardní definice mexEndpoint:

> konfigurace <

  <system.serviceModel>

    > služeb <

      <service name="GreetingService">

        <endpoint kind="basicHttpBinding" contract="IHello"/>

        <endpoint kind="mexEndpoint" address="mex" />

      </service>

    </services>

  </system.serviceModel>

</configuration>

I když vás standardní koncové body chrání od většiny podrobností konfigurace (např. u mexEndpointu, který jsem nemusel zadávat vazbu nebo kontrakt), může se stát, že je budete chtít použít, ale potřebujete nakonfigurovat standardní definice koncových bodů trochu jinak. 

Pokud to potřebujete udělat, můžete použít <standardEndpoints> oddíl a přepsat konfiguraci koncového bodu pro standardní koncový bod. Na tuto konfiguraci pak můžete odkazovat při definování nového koncového bodu <> prostřednictvím atributu endpointConfiguration, jak je znázorněno tady:

> konfigurace <

  <system.serviceModel>

    > služeb <

      <service name="GreetingService">

        <endpoint binding="basicHttpBinding" contract="IHello"/>

        <endpoint kind="udpDiscoveryEndpoint" endpointConfiguration="D11"/>

      </service>

    </services>

    <standardEndpoints>

      <udpDiscoveryEndpoint>

        <standardEndpoint name="D11" discoveryVersion="WSDiscovery11"/>

      </udpDiscoveryEndpoint>

    </standardEndpoints>

    <chování>

      <serviceBehaviors>

        > chování <

          <serviceDiscovery/>

          <serviceMetadata httpGetEnabled="true"/>

        </behavior>

      </serviceBehaviors>

    </behaviors>

  </system.serviceModel>

</configuration>

V tomto příkladu dojde ke změně výchozí verze WS-Discovery standardního koncového bodu s názvem udpDiscoveryEndpoint (za chvíli se budeme zabývat zjišťováním služeb).

Zjednodušení hostování SLUŽBY IIS/ASP.NET

Vzhledem k těmto novým funkcím pro výchozí koncové body, výchozí konfigurace vazeb a konfigurace výchozího chování se hostování ve službě IIS/ASP.NET v WCF 4 výrazně zjednoduší. ASP.NET vývojáři, kteří se používají k práci se službami ASMX, teď můžou definovat služby WCF, které jsou v podstatě stejně jednoduché.

Ve skutečnosti se podívejte, jak jednoduchá je následující definice služby WCF:

<!-- HelloWorld.svc –>

<%@ ServiceHost Language="C#" Debug="true" Service="HelloWorldService

    CodeBehind="~/App_Code/HelloWorldService.cs" %>

[ServiceContract]

veřejná třída HelloWorldService

{

    [OperationContract]

    veřejný řetězec HelloWorld()

    {

        návrat "hello, world";

    }

}

Toto je nejjednodušší forma definice služby WCF, protože nepoužíváme samostatnou definici rozhraní k definování kontraktu služby a vše je definováno v jednom souboru HelloWorld.svc (poznámka: Nedoporučuji tento přístup, jen si všimněte, že je možné nakreslit porovnání s ASMX). To by se mělo zdát hodně jako typické služby ASMX, primární rozdíl je názvy atributů, které používáte ve třídě služby (např. [WebService] a [WebMethod]). Určitě je méně pohyblivých částí.

S novými funkcemi WCF 4 popsanými v předchozí části teď můžete přejít na HelloWorld.svc bez jakékoli další konfigurace WCF a logika aktivace WCF vytvoří instanci ServiceHost na pozadí a nakonfiguruje ji s jedním výchozím koncovým bodem HTTP. A pokud jste do souboru s povolením metadat služby machine.config přidali výchozí chování služby, zobrazí se stránka nápovědy WCF a odkaz na definici WSDL při přechodu na HelloWorld.svc (viz obrázek 8).

obrázek 8: Stránka nápovědy HelloWorldService

Pokud jste nepovolili metadata služby v celém počítači, můžete ji povolit ve webové aplikaci přidáním následující výchozí konfigurace chování do souboru web.config:

...

<system.serviceModel>

  <chování>

    <serviceBehaviors>

      <chování><!-- si všimněte, že neexistuje žádný atribut názvu –>

         <serviceMetadata httpGetEnabled="true"/>

      </behavior>

    </serviceBehaviors>

  </behaviors>

</system.serviceModel>

...

Další výchozí nastavení můžete také změnit podle postupů popsaných v předchozích částech. Můžete například změnit výchozí mapování protokolu, přidat výchozí konfigurace vazeb nebo další výchozí konfigurace chování. Pokud služba implementuje více než jeden kontrakt služby, bude výsledná instance ServiceHost nakonfigurována s jedním koncovým bodem HTTP na kontrakt.

Předpokládejme například, že hostujeme naši službu GreetingService (od dřívějšího) prostřednictvím souboru .svc, který je zde uvedený:

<!-- GreetingService.svc –>

<%@ServiceHost Service="GreetingService"%>

Vzhledem k naší definici pro GreetingService se při prvním přechodu na GreetingService.svc vytvoří aktivační logika WCF instanci ServiceHost a přidá dva výchozí koncové body HTTP pro typ GreetingService (jeden pro každý kontrakt služby). Můžete to ověřit tak, že přejdete do definice WSDL a v elementu <> služby> najdete dva <elementy> portu.

Celkově by tato zjednodušení konfigurace WCF měla usnadnit ASP.NET vývojářům zprovoznit služby WCF v rámci svých webových aplikací a přináší nejjednodušší případ mnohem blíž prostředí, které vývojáři používali s ASP.NET webovými službami.

Aktivace bez souborů

I když soubory .svc usnadňují zveřejnění služeb WCF, ještě jednodušším přístupem by bylo definovat koncové body virtuální aktivace v rámci Web.config, čímž se zcela odstraňuje potřeba souborů .svc.

Ve WCF 4 můžete definovat koncové body aktivace virtuální služby, které se mapují na typy služeb v Web.config. To umožňuje aktivovat služby WCF bez nutnosti udržovat fyzické soubory .svc (a.k.a. "aktivace bez souborů"). Následující příklad ukazuje, jak nakonfigurovat koncový bod aktivace:

> konfigurace <

  <system.serviceModel>

    <serviceHostingEnvironment>

      <serviceActivations>

        <přidat relativeAddress="Greeting.svc" service="GreetingService"/>

      </serviceActivations>

    </serviceHostingEnvironment>

  </system.serviceModel>

</configuration>

Díky tomu je nyní možné aktivovat službu GreetingService pomocí relativní cesty "Greeting.svc" (vzhledem k základní adrese webové aplikace). Abychom to mohli ilustrovat, vytvořil(a) jsem na svém počítači aplikaci IIS s názvem "GreetingSite", kterou jsem přiřadil k fondu aplikací "ASP.NET v4.0" a namapoval ho do adresáře projektu GreetingService, který obsahuje web.config uvedené výše. Teď můžu jednoduše procházet https://localhost/GreetingSite/Greeting.svc bez skutečného fyzického souboru .svc na disku. Obrázek 9 ukazuje, jak to vypadá v prohlížeči.

Obrázek 9: Příklad aktivace bez souborů

Objev

Další hlavní funkcí WCF 4, kterou probereme, je zjišťování služeb. V některýchch Představte si například prostředí, kde se různé typy zařízení s podporou služeb neustále připojují a opouštějí síť jako součást celkového obchodního řešení. Práce s touto realitou vyžaduje, aby klienti dynamicky zjistili umístění modulu runtime koncových bodů služby.

WS-Discovery je specifikace OASIS, která definuje protokol založený na protokolu SOAP pro dynamické zjišťování umístění koncových bodů služby za běhu. Protokol umožňuje klientům testovat koncové body služby, které splňují určitá kritéria, aby získali seznam vhodných kandidátů. Klient pak může zvolit konkrétní koncový bod ze seznamu zjištěných položek a použít jeho aktuální adresu koncového bodu modulu runtime.

WS-Discovery definuje dva primární režimy provozu: ad hoc režim a spravovaný režim. V ad hoc režimu klienti testují služby odesíláním zpráv vícesměrového vysílání. Architektura poskytuje mechanismus vícesměrového vysílání UDP pro tento ad hoc režim. Služby, které odpovídají sondě, reagují přímo na klienta. Aby se minimalizovala potřeba dotazování klientů, můžou se služby při připojování k síti nebo opuštění sítě "oznamovat" odesláním zprávy vícesměrového vysílání klientům, kteří můžou "naslouchat". Ad hoc zjišťování je omezeno protokolem používaným pro zprávy vícesměrového vysílání, v případě udp budou moci zprávy přijímat pouze služby, které naslouchají v místní podsíti.

Pomocí zjišťování spravovaných služeb poskytnete proxy zjišťování v síti, která "spravuje" zjistitelné koncové body služby. Klienti komunikují přímo s proxy zjišťováním a vyhledá služby na základě kritérií zjišťování. Proxy zjišťování potřebuje úložiště služeb, které se můžou shodovat s dotazem. Způsob, jakým je proxy server naplněný touto informací, je podrobnosti implementace. Proxy servery zjišťování se dají snadno připojit k exisiting úložišti služeb, můžou být předem nakonfigurované se seznamem koncových bodů nebo proxy zjišťování může dokonce naslouchat oznámením o aktualizaci mezipaměti. V režimu spravovaného může být oznámení jednosměrové vysílání přímo příjemci, potenciálně proxy zjišťováním.

Rozhraní .NET 4.0 poskytuje základní třídy, které potřebujete implementovat vlastní proxy zjišťování. Základní třídy abstrahuje podrobnosti protokolu zjišťování, abyste se mohli jednoduše zaměřit na logiku, kterou má proxy zjišťování obsahovat. Potřebujete například definovat, co bude proxy zjišťování provádět v reakci na zprávu sondy, zprávy oznámení a překlad zpráv.

WCF 4 poskytuje úplnou implementaci protokolu WS-Discovery a poskytuje podporu pro ad hoc i spravované režimy zjišťování. Na každou z těchto možností se podíváme krátce níže.

Jednoduché zjišťování služeb

Nejjednodušší způsob, jak povolit zjišťování služby, je prostřednictvím ad hoc režimu. WCF usnadňuje povolení zjišťování služeb v rámci hostitelských aplikací služby tím, že poskytuje některé standardní koncové body zjišťování a chování zjišťování služby. Pokud chcete nakonfigurovat službu pro zjišťování, jednoduše přidejte standardní koncový bod udpDiscoveryEndpoint a pak povolte chování služby <serviceDiscovery> ve službě.

Tady je úplný příklad znázorňující, jak to udělat:

> konfigurace <

    <system.serviceModel>

      > služeb <

        <service name="CalculatorService">

          <endpoint binding="wsHttpBinding" contract="ICalculatorService" />

          <!-- přidání standardního koncového bodu zjišťování UDP –>

          <název koncového bodu="udpDiscovery" kind="udpDiscoveryEndpoint"/>

        </service>

      </services>

      <chování>

        <serviceBehaviors>

          > chování <

            <serviceDiscovery/><!-- povolit chování zjišťování služby –>

          </behavior>

        </serviceBehaviors>

      </behaviors>

    </system.serviceModel>

</configuration>

Tím se vaše služba stane zjistitelnou přes UDP v místní podsíti. Klienti pak můžou využít WS-Discovery za běhu a zjistit skutečnou adresu spuštěné služby. WCF 4 usnadňuje klientům, aby toho dosáhli prostřednictvím dynamického koncového bodu standarduEndpoint.

Jednoduše vezměte existující koncový bod klienta, který jste používali pro připojení ke službě, odeberte adresu a přidejte značku kind="dynamicEndpoint".

> konfigurace <

    <system.serviceModel>

        > klienta <

          koncový bod <

              name="calculatorEndpoint"

              kind="dynamicEndpoint"

              binding="wsHttpBinding"

              contract="ICalculatorService">

          </endpoint>

        </client>

    </system.serviceModel>

</configuration>

Při prvním volání služby klient odešle dotaz vícesměrového vysílání, který hledá služby, které odpovídají kontraktu ICalculatorService a pokusí se připojit k jednomu. Různá nastavení umožňují doladit serach, upravit vazby zjišťování a řídit proces zjišťování. Všechny tyto akce můžete provádět také prostřednictvím kódu programu pomocí třídy DiscoveryClient.

Následující příklad dále ukazuje, jak pomocí UdpDiscoveryEndpoint programově zjistit koncový bod ICalculatorService a pak ho vyvolat:

Vytvoření DiscoveryClient

DiscoveryClient discoveryClient =

    new DiscoveryClient(new UdpDiscoveryEndpoint());

Vyhledání koncových bodů ICalculatorService v zadaném oboru

FindCriteria findCriteria = new FindCriteria(typeof(ICalculatorService));

FindResponse findResponse = discoveryClient.Find(findCriteria);

Stačí vybrat první zjištěný koncový bod.

Adresa EndpointAddress = findResponse.Endpoints[0]. Adresa;

Vytvoření klienta cílové služby

Klient CalculatorServiceClient =

    new CalculatorServiceClient("calculatorEndpoint");

Připojení ke zjištěnému koncovému bodu služby

klient. Endpoint.Address = adresa;

Console.WriteLine("Vyvolání CalculatorService na {0}", adresa);

Volejte operaci Přidat službu.

double result = client. Add(100; 15.99);

Console.WriteLine("Add({0};{1}) = {2}"; 100; 15,99; výsledek);

Jakmile klientský program načte kolekci zjištěných koncových bodů, může použít jeden z nich k skutečnému vyvolání cílové služby. Obrázek 10 ukazuje výstup spuštění výše uvedeného kódu klienta za předpokladu, že služba běží současně. Poznámka: V tomto příkladu je operace Najít na klientovi zjišťování synchronní; zjišťování poskytuje také podporu asynchronních operací hledání.

Obrázek 10: Výstup spuštění kódu klienta zjišťování

Použití oborů při zjišťování koncových bodů

V předchozím příkladu klient jednoduše probírá služby na základě typu kontraktu služby. Klienti můžou výsledky zjišťování zúžit tím, že při odesílání sond zjišťování poskytnou další informace o rozsahu. Podívejme se na jednoduchý příklad, abychom zjistili, jak se dají během zjišťování používat "obory".

Nejprve musí služba přidružit jeden nebo více oborů ke každému koncovému bodu, který bude publikovat pro zjišťování. WCF 4 obsahuje <chování koncového boduDiscovery>, které můžete použít k definování sady oborů, které můžete přidružit k definici koncového bodu. Následující příklad ukazuje, jak přidružit dva obory k jednomu koncovému bodu definovanému ve službě:

> konfigurace <

    <system.serviceModel>

      > služeb <

        <service name="CalculatorService"

                 behaviorConfiguration="calculatorServiceBehavior">

          <endpoint binding="wsHttpBinding"

                    contract="ICalculatorService"

                    behaviorConfiguration="ep1Behavior" />

          <název koncového bodu="udpDiscovery" kind="udpDiscoveryEndpoint"/>

        </service>

      </services>

      <chování>

        <serviceBehaviors>

          <behavior name="calculatorServiceBehavior">

            <serviceDiscovery/>

          </behavior>

        </serviceBehaviors>

        <koncové bodyBehaviors>

          <behavior name="ep1Behavior">

            <endpointDiscovery>

               <!-- rozsahy přidružené k tomuto chování koncového bodu –>

              rozsahy <>

                <přidat scope="http://www.example.org/calculator"/>

                <přidat scope="ldap:///ou=engineering,o=exampleorg,c=us"/>

              </scopes>

            </endpointDiscovery>

          </behavior>

         </endpointBehaviors>

      </behaviors>

    </system.serviceModel>

</configuration>

Klienti můžou testovat koncové body služby na základě konkrétních oborů za běhu. Můžou to udělat přidáním seznamu cílových oborů do instance FindCriteria, kterou zadáte operaci Najít. Následující kód ukazuje, jak zjistit koncové body ICalculatorService odpovídající určitému oboru LDAP:

...

Vytvoření DiscoveryClient

DiscoveryClient discoveryClient = new DiscoveryClient("udpDiscoveryEndpoint");

Vyhledání koncových bodů ICalculatorService v zadaném oboru

Obor URI = nový identifikátor URI("ldap:///ou=engineering,o=exampleorg,c=us");

FindCriteria findCriteria = new FindCriteria(typeof(ICalculatorService));

findCriteria.Scopes.Add(scope);

FindResponse findResponse = discoveryClient.Find(findCriteria);

...

Využití rozsahů umožňuje doladit implementaci zjišťování, aby klienti mohli snadněji zjišťovat konkrétní koncové body služby, které jsou pro ně zajímavé. Zjišťování umožňuje také další přizpůsobení. Služby můžou například do koncového bodu přidat vlastní metadata XML. Tyto informace se posílají klientovi v reakci na dotaz klienta.

Oznámení služby

WCF 4 také usnadňuje konfiguraci služeb, které "oznamují" jejich koncové body při spuštění. To umožňuje klientům, kteří "naslouchají", získat informace o nových koncových bodech služby přímo při připojení k síti, a tím snížit množství sondování (a zasílání zpráv vícesměrového vysílání) prováděné klienty.

Službu můžete nakonfigurovat s koncovým bodem oznámení pomocí chování <serviceDiscovery>. Chování <serviceDiscovery> umožňuje definovat kolekci koncových bodů oznámení, které bude služba vystavit. Ve většině případů můžete použít standardní "udpAnnouncementEndpoint".

Pokud chcete, aby služba reagovala na sondy zjišťování iniciované klienty, stále budete muset službu nakonfigurovat se standardním "udpDiscoveryEndpointem". Následující příklad ukazuje typickou konfiguraci:

> konfigurace <

  <system.serviceModel>

    > služeb <

      <service name="CalculatorService">

        <endpoint binding="wsHttpBinding" contract="ICalculatorService"/>

        <endpoint kind="udpDiscoveryEndpoint"/>

      </service>

    </services>

    <chování>

      <serviceBehaviors>

        > chování <

          <serviceDiscovery>

            <oznámeníEndpoints>

              <endpoint kind="udpAnnouncementEndpoint"/>

            </announcementEndpoints>

          </serviceDiscovery>

        </behavior>

      </serviceBehaviors>

    </behaviors>

  </system.serviceModel>

</configuration>

Když je tato konfigurace nastavená, služba oznámí sama sebe, když je online, a oznámí také, kdy přejde do režimu offline. Abyste mohli tato oznámení využít, budete muset navrhnout klienty tak, aby je mohli naslouchat za běhu. Provedete to hostováním služby oznámení v klientské aplikaci, která implementuje protokol oznámení WS-Discovery.

WCF 4 se dodává s třídou s názvem AnnouncementService navržená speciálně pro tento účel. Služba AnnouncementService poskytuje dva obslužné rutiny událostí: OnlineAnnouncementReceived a OfflineAnnouncementReceived. Klientské aplikace mohou jednoduše hostovat instanci služby AnnouncementService pomocí ServiceHost a zaregistrovat obslužné rutiny událostí pro tyto dvě události.

Kdykoli služba přijde online a oznámí sama sebe, služba Oznámení hostovaná klientem obdrží oznámení online a OnlineAnnouncementReceived se aktivuje v klientovi. Když služba přejde do offline režimu, odešle oznámení "offline" a OfflineAnnouncementReceived se aktivuje v klientovi. Následující příklad ukazuje ukázkovou klientskou aplikaci, která je hostitelem služby AnnouncementService, a implementuje obslužné rutiny pro dvě události oznámení:

Třída Klient

{

    public static void Main()

    {

        Vytvoření instance AnnouncementService

        AnnouncementService announcementService = new AnnouncementService();

        Přihlášení k odběru událostí oznámení

        announcementService.OnlineAnnouncementReceived += OnOnlineEvent;

        announcementService.OfflineAnnouncementReceived += OnOfflineEvent;

        Vytvoření servicehost pro službu AnnouncementService

        using (ServiceHost announcementServiceHost =

            new ServiceHost(announcementService))

        {

            Poslech oznámení odesílaných přes vícesměrové vysílání UDP

            announcementServiceHost.AddServiceEndpoint(

                new UdpAnnouncementEndpoint());

            announcementServiceHost.Open();

            Console.WriteLine("Naslouchání oznámením služby");

            Console.WriteLine();

            Console.WriteLine("Stisknutím klávesy <ENTER> ukončete.");

            Console.ReadLine();

        }

    }

    static void OnOnlineEvent(object sender, AnnouncementEventArgs e)

    {

        Console.WriteLine();

        Console.WriteLine("Obdrželo online oznámení z {0}:",

            e.EndpointDiscoveryMetadata.Address);

        PrintEndpointDiscoveryMetadata(e.EndpointDiscoveryMetadata);

    }

    static void OnOfflineEvent(object sender, AnnouncementEventArgs e)

    {

        Console.WriteLine();

        Console.WriteLine("Přijaté offline oznámení z {0}:",

            e.EndpointDiscoveryMetadata.Address);

        PrintEndpointDiscoveryMetadata(e.EndpointDiscoveryMetadata);

    }

    ...

}

Obrázek 11: Naslouchání zprávům oznámení o zjišťování

Teď předpokládejme, že spustím tento klientský program a chvíli ho nechám spuštěný. Později spustím několik instancí hostitelské aplikace služby. Když se spustí každý z nich, zobrazí se v okně konzoly klienta zpráva s oznámením online. Když zavřem každou z hostitelských aplikací služby, zobrazí se v okně konzoly klienta zpráva s oznámením "offline". Obrázek 11 znázorňuje výsledné okno konzoly klienta po tom, co jsem právě popsal.

Nezapomeňte, že režim ad hoc zjišťování funguje jenom v místní podsíti. Pokud chcete použít WS-Discovery za hranicemi místní sítě, budete muset přejít do režimu spravovaného zjišťování. WCF 4 poskytuje podporu pro vytváření nezbytných komponent spravovaného zjišťování.

Zjišťování spravovaných služeb

Implementace režimu spravovaného zjišťování je o něco více zapojená než režim ad hoc, protože vyžaduje implementaci služby proxy zjišťování. Služba proxy zjišťování je komponenta, která bude sledovat všechny dostupné koncové body služby. V tomto příkladu používáme funkci oznámení k aktualizaci proxy zjišťování. Existuje mnoho dalších způsobů, jak poskytnout proxy zjišťování s relevantními informacemi o zjišťování, například můžete připojit existující databázi koncových bodů a zachytávat data odtud. Jak tedy implementujete službu proxy zjišťování?

WCF 4 obsahuje základní třídu s názvem DiscoveryProxy, ze které můžete odvodit implementaci služby proxy zjišťování. Obrázek 12 znázorňuje začátek vlastní implementace služby proxy zjišťování. Ukázky sady .NET 4 SDK obsahují úplnou ukázkovou implementaci pro vaši referenci. Jakmile dokončíte implementaci služby proxy zjišťování, musíte ji někam hostovat.

Obrázek 12: Implementace vlastní služby proxy zjišťování

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single,

    ConcurrencyMode = ConcurrencyMode.Multiple)]

veřejná třída MyDiscoveryProxy: DiscoveryProxyBase

{

    Úložiště pro ukládání EndpointDiscoveryMetadata.

    Místo toho je možné použít databázi nebo plochý soubor.

    Slovník<EndpointAddress, EndpointDiscoveryMetadata> onlineServices;

    public MyDiscoveryProxy()

    {

        this.onlineServices =

            new Dictionary<EndpointAddress, EndpointDiscoveryMetadata>();

    }

    OnBeginOnlineAnnouncement se volá, když proxy server přijme zprávu Hello.

    protected override IAsyncResult OnBeginOnlineAnnouncement(

        DiscoveryMessageSequence messageSequence, EndpointDiscoveryMetadata

        endpointDiscoveryMetadata, zpětné volání AsyncCallback, stav objektu)

    {

        toto. AddOnlineService(endpointDiscoveryMetadata);

        return new OnOnlineAnnouncementAsyncResult(callback, state);

    }

    protected override void OnEndOnlineAnnouncement(IAsyncResult result)

    {

        OnOnlineAnnouncementAsyncResult.End(result);

    }

    OnBeginOfflineAnnouncement se volá, když proxy server přijme zprávu bye

    protected override IAsyncResult OnBeginOfflineAnnouncement(

        DiscoveryMessageSequence messageSequence, EndpointDiscoveryMetadata

        endpointDiscoveryMetadata, zpětné volání AsyncCallback, stav objektu)

    {

        toto. RemoveOnlineService(endpointDiscoveryMetadata);

        return new OnOfflineAnnouncementAsyncResult(callback, state);

    }

    protected override void OnEndOfflineAnnouncement(IAsyncResult result)

    {

        OnOfflineAnnouncementAsyncResult.End(result);

    }

    OnBeginFind se volá, když proxy server přijme zprávu požadavku sondy.

    protected override IAsyncResult OnBeginFind(

        FindRequestContext findRequestContext, zpětné volání AsyncCallback, stav objektu)

    {

        toto. MatchFromOnlineService(findRequestContext);

        return new OnFindAsyncResult(callback, state);

    }

    protected override void OnEndFind(IAsyncResult result)

    {

        OnFindAsyncResult.End(result);

    }

    ...

V tomto příkladu jednoduše hostuji službu MyDiscoveryProxy v konzolové aplikaci.  Nakonfiguruji hostitele se dvěma koncovými body: koncovým bodem zjišťování a koncovým bodem oznámení. Následující příklad ukazuje, jak správně hostovat službu MyDiscoveryProxy s oběma těmito koncovými body:

program třídy

{

    public static void Main()

    {

        Uri probeEndpointAddress = new Uri("net.tcp://localhost:8001/Probe");

        Uri announcementEndpointAddress =

            new Uri("net.tcp://localhost:9021/Announcement");

        ServiceHost proxyServiceHost = new ServiceHost(new MyDiscoveryProxy());

        DiscoveryEndpoint discoveryEndpoint = new DiscoveryEndpoint(

            new NetTcpBinding(), new EndpointAddress(probeEndpointAddress));

        discoveryEndpoint.IsSystemEndpoint = false;

        AnnouncementEndpoint announcementEndpoint = new AnnouncementEndpoint(

            new NetTcpBinding(), new EndpointAddress(announcementEndpointAddress));

        proxyServiceHost.AddServiceEndpoint(discoveryEndpoint);

        proxyServiceHost.AddServiceEndpoint(announcementEndpoint);

        proxyServiceHost.Open();

        Console.WriteLine("Služba proxy byla spuštěna.");

        Console.WriteLine();

        Console.WriteLine("Stisknutím klávesy <ENTER> ukončíte službu.");

        Console.WriteLine();

        Console.ReadLine();

        proxyServiceHost.Close();

    }

}

Jakmile máte spuštěnou a spuštěnou službu proxy zjišťování, můžete nakonfigurovat služby tak, aby se oznamovaly přímo službě proxy zjišťování. Stejně tak můžete klientské aplikace nakonfigurovat tak, aby testovali službu proxy zjišťování přímo (žádné vícesměrové zasílání zpráv).

Službu nakonfigurujete tak, aby se oznamovala přímo službě proxy zjišťování zadáním adresy oznámení proxy zjišťování při vytváření bodu OznámeníEndpoint v rámci hostitelské aplikace služby. Následující příklad ukazuje, jak toho dosáhnout:

...

Uri baseAddress = new Uri("net.tcp://localhost:9002/CalculatorService/" +

    Guid.NewGuid(). ToString());

Uri announcementEndpointAddress = new Uri("net.tcp://localhost:9021/Announcement");

ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService), baseAddress);

ServiceEndpoint netTcpEndpoint = serviceHost.AddServiceEndpoint(

    typeof(ICalculatorService), nový NetTcpBinding(), řetězec. Prázdné);

Vytvoření koncového bodu oznámení odkazujícího na hostované proxy služby

AnnouncementEndpoint announcementEndpoint = new AnnouncementEndpoint(

    new NetTcpBinding(), new EndpointAddress(announcementEndpointAddress));

ServiceDiscoveryBehavior serviceDiscoveryBehavior = new ServiceDiscoveryBehavior();

serviceDiscoveryBehavior.AnnouncementEndpoints.Add(announcementEndpoint);

serviceHost.Description.Behaviors.Add(serviceDiscoveryBehavior);

serviceHost.Open();

...

Potom můžete klientské aplikace nakonfigurovat tak, aby komunikily přímo se službou proxy zjišťování zadáním adresy sondy proxy zjišťování při vytváření bodu DiscoveryEndpoint v rámci klientské aplikace. Následující příklad ukazuje jeden ze způsobů, jak to udělat:

...

Vytvořte koncový bod zjišťování, který odkazuje na službu proxy.

Uri probeEndpointAddress = new Uri("net.tcp://localhost:8001/Probe");

DiscoveryEndpoint discoveryEndpoint = new DiscoveryEndpoint(

    new NetTcpBinding(), new EndpointAddress(probeEndpointAddress));

Vytvoření DiscoveryClient pomocí dříve vytvořeného discoveryEndpointu

DiscoveryClient discoveryClient = new DiscoveryClient(discoveryEndpoint);

Vyhledání koncových bodů ICalculatorService

FindResponse findResponse = discoveryClient.Find(

    new FindCriteria(typeof(ICalculatorService)));

...

Teď si projdeme kompletní příklad. Nejprve spustím aplikaci proxy zjišťování, aby byla služba proxy zjišťování k dispozici pro použití. Pak spustím instanci hostitelské aplikace služby, která oznámí, že se používá proxy zjišťování. Jakmile k tomu dojde, zobrazí se zpráva vytištěná do okna konzoly aplikace proxy zjišťování (viz obrázek 13). To ilustruje, že služba oznámila, že proxy zjišťování úspěšně oznámila, a proxy zjišťování uložil informace o novém koncovém bodu online služby. Když teď spustíme výše uvedený kód klienta, testuje proxy zjišťování přímo a načte adresu koncového bodu cílové služby, která je aktuálně spuštěná.

Obrázek 13: Výstup ze služby proxy zjišťování za běhu

Výhodou zjišťování spravovaných služeb je, že funguje přes hranice sítě (je založená na tradičních voláních služeb) a snižuje potřebu zasílání zpráv vícesměrového vysílání v rámci řešení zjišťování. Kromě toho vzhledem k tomu, že klienti procházejí proxy zjišťováním, aby hledali služby, nemusí být samotné služby neustále spuštěné, aby bylo možné zjistit.

Rozšířené využití proxy serveru zjišťování

Programovací model WCF poskytuje velkou flexibilitu při implementaci proxy zjišťování. Příjem oznámení je jedním ze způsobů, jak naplnit seznam služeb; nejedná se však o jedinou metodu. Pokud například vaše prostředí již obsahuje úložiště služby, můžete snadno vytvořit fasádu proxy zjišťování nad tímto úložištěm, aby bylo možné úložiště zjistit za běhu.

Proxy zjišťování je možné nastavit v ad hoc režimu nebo v režimu správy. Při provozu v spravovaném režimu komunikují klienti s proxy přímo jednosměrovým způsobem pomocí oznámení, sond a překladů. Proxy server také předá odpověď jednosměrovým způsobem zpět odesílateli.

Pokud funguje v ad hoc režimu, může proxy naslouchat zprávům zjišťování vícesměrového vysílání a odpovídat přímo odesílateli. V tomto ad hoc režimu lze proxy server nakonfigurovat také tak, aby potlačit zprávy vícesměrového vysílání. To znamená, že pokud proxy obdrží zprávu vícesměrového vysílání, informuje odesílatele o jeho přítomnosti a informuje odesílatele, aby směrovala další dotazy na proxy serveru, a tím se vyhnula dalším zprávám vícesměrového vysílání.

Další informace o těchto pokročilých scénářích zjišťování naleznete v WS-Discovery Primer na http://www.oasis-open.org/committees/download.php/32184/WS-D-primer-wd-04.docx.

Směrovací služba

V některých prostředích orientovaných na služby je často užitečné využít centralizované "směrovací" služby, které fungují jako zprostředkovatelé nebo brány do skutečných obchodních služeb rozptýlených v organizaci. Tím se oddělí spotřebitelé od skutečných obchodních služeb a umožní provádět různé typy zprostředkujícího zpracování v rámci uzlu směrování.

Některá prostředí například používají směrování k implementaci centralizované hranice zabezpečení, kterou musí procházet všechny příchozí zprávy. Některé používají techniky směrování založené na obsahu k určení cílové služby, která se má použít na základě obsahu konkrétní příchozí zprávy. Jiní používají směrování k implementaci přemostění protokolu, což uživatelům umožňuje komunikovat pomocí jedné sady protokolů, zatímco směrovač používá k komunikaci s cílovou službou jinou sadu protokolů. Také není neobvyklé používat směrování pro různé techniky vyrovnávání zatížení nebo dokonce správy verzí služeb.

Bez ohledu na to, proč je vzor "průběžného směrování" běžným požadavkem při vytváření rozsáhlých řešení SOA. V WCF 3.x nebyla oficiální podpora směrování. I když architektura poskytovala potřebná rozhraní API pro implementaci vlastních směrovacích služeb, bylo to hodně práce, jak to udělat správně. V MSDN Magazine bylo publikováno několik článků, které ukazují, jak toho dosáhnout.

Vzhledem k tomu, že směrování je v těchto dnech běžným požadavkem, technologie WCF 4 je nyní součástí oficiální "směrovací služby", kterou můžete jednoduše hostovat a konfigurovat ve vlastních řešeních.

Principy služby RoutingService

WCF 4 obsahuje novou třídu s názvem RoutingService, která poskytuje obecnou implementaci směrování WCF pro použití v rámci vašich aplikací. Služba RoutingService dokáže zpracovávat směrovací zprávy přes libovolný protokol podporovaný wcf pomocí různých vzorů zasílání zpráv, jako jsou jednosměrné, odpovědi na požadavky a duplexní zasílání zpráv). Následující příklad ukazuje definici třídy RoutingService:

[ServiceBehavior(AddressFilterMode = AddressFilterMode.Any;

    InstanceContextMode = InstanceContextMode.PerSession,

    UseSynchronizationContext = false, ValidateMustUnderstand = false),

 AspNetCompatibilityRequirements(RequirementsMode =

    AspNetCompatibilityRequirementsMode.Allowed)]

veřejná zapečetěná třída RoutingService : // kontrakty umožňují různé komunikační vzory.

    ISimplexDatagramRouter, ISimplexSessionRouter, IRequestReplyRouter,

    IDuplexSessionRouter, IDisposable

{

    ... // Implementace není vynechána.

}

Jak vidíte, třída RoutingService je odvozena z více kontraktů služeb, aby podporovala více vzorů zasílání zpráv. Každý kontrakt služby poskytuje podporu pro jiný vzor zasílání zpráv, včetně podpory komunikace založené na relacích, pokud je to vhodné.

Účelem služby RoutingService je přijímat příchozí zprávy od příjemců a směrovat je do příslušné podřízené služby. RouterService určuje, kterou cílovou službu použít, vyhodnocením jednotlivých příchozích zpráv v sadě filtrů zpráv. Proto jako vývojář řídíte chování směrování definováním filtrů zpráv, obvykle v konfiguračním souboru. Cílové služby se můžou nacházet ve stejném počítači jako RouterService, ale nemusí – můžou být také distribuovány v síti a můžou vyžadovat různé protokoly.

Hostování služby RoutingService

Službu RoutingService můžete ve své aplikaci hostovat stejně jako jakoukoli jinou službu WCF. Jednoduše vytvoříte instanci ServiceHost a zadáte RoutingService pro typ služby. Jakmile zavoláte Open v instanci ServiceHost, služba RoutingService bude připravená ke směrování zpráv, jak je znázorněno zde:

pomocí systému;

pomocí System.ServiceModel;

pomocí System.ServiceModel.Routing;

public static void Main()

{

    Vytvořte ServiceHost pro typ RoutingService.

    using (ServiceHost serviceHost =

        new ServiceHost(typeof(RoutingService)))

    {

        zkusit

        {

            serviceHost.Open();

            Console.WriteLine("Služba směrování je nyní spuštěna.");

            Console.WriteLine("Stisknutím klávesy <ENTER> ukončete směrovač.");

            Služba je teď přístupná.

            Console.ReadLine();

            serviceHost.Close();

        }

        catch (CommunicationException)

        {

            serviceHost.Abort();

        }

    }

}

Službu RoutingService také nakonfigurujete stejně jako jakoukoli jinou službu a tam definujete filtry směrování. Nejprve je potřeba ho nakonfigurovat s jedním nebo více koncovými body. Při definování koncového bodu směrování zvolíte vazbu WCF a jeden z kontraktů služby směrování implementovaných službou RoutingService uvedenou výše (např. ISimplexDatagramRouter, IRequestReplyRouter atd.). Pokud chcete podporovat více vzorů zasílání zpráv nebo vazby WCF, můžete ve službě RoutingService zveřejnit více než jeden koncový bod.

Následující příklad ukazuje, jak nakonfigurovat službu RoutingService se čtyřmi koncovými body směrování: dvěma, které používají rutinu BasicHttpBinding (jednosměrnou a žádost-odpověď) a dvě, které používají WSHttpBinding (jednosměrná a žádost-odpověď). Všimněte si, že je to stejně jako konfigurace jakékoli jiné služby WCF:

> konfigurace <

  <system.serviceModel>

    > služeb <

      <!--ROUTING SERVICE –>

      <service behaviorConfiguration="routingData"

          name="System.ServiceModel.Routing.RoutingService">

        > hostitele <

          < > baseAddresses

            <přidat baseAddress="https://localhost:8000/routingservice/router"/>

          </baseAddresses>

        </host>

        <!--

          Definujte a nakonfigurujte koncový bod, na který chce směrovač naslouchat, a na

          Kontrakt chceme použít. Zadané kontrakty směrovačů:

          ISimplexDatagramRouter, ISimplexSessionRouter, IRequestReplyRouter a

          IDuplexSessionRouter.

         ->

        <endpoint address="oneway-basic"

                  binding="basicHttpBinding"

                  name="onewayEndpointBasic"

                  contract="System.ServiceModel.Routing.ISimplexDatagramRouter" />

        <adresa koncového bodu="oneway-ws"

                  binding="wsHttpBinding"

                  name="onewayEndpointWS"

                  contract="System.ServiceModel.Routing.ISimplexDatagramRouter" />

        <endpoint address="twoway-basic"

                  binding="basicHttpBinding"

                  name="reqReplyEndpointBasic"

                  contract="System.ServiceModel.Routing.IRequestReplyRouter" />

        <endpoint address="twoway-ws"

                  binding="wsHttpBinding"

                  name="reqReplyEndpointWS"

                  contract="System.ServiceModel.Routing.IRequestReplyRouter" />

      </service>

    </services>

    ...

Rozhraní ISimplexDatagramRouter a IRequestReplyRouter definují obecné jednosměrné definice kontraktů služeb a kontraktů odpovědí na žádosti, které lze použít ve spojení s kontrakty služeb specifických pro firmy. Následující příklad ukazuje, jak byla tato rozhraní definována ve WCF:

[ServiceContract(Namespace="https://schemas.microsoft.com/netfx/2009/05/routing",

    SessionMode = SessionMode.Allowed)]

veřejné rozhraní ISimplexDatagramRouter

{

    [OperationContract(AsyncPattern = true, IsOneWay = true, Action = "*")]

    IAsyncResult BeginProcessMessage(zpráva zprávy, zpětné volání AsyncCallback,

        stav objektu);

    void EndProcessMessage(výsledek IAsyncResult);

}

[ServiceContract(Namespace="https://schemas.microsoft.com/netfx/2009/05/routing",

    SessionMode = SessionMode.Allowed)]

veřejné rozhraní IRequestReplyRouter

{

    [OperationContract(AsyncPattern = true, IsOneWay= false, Action = "*",

        ReplyAction = "*")]

    [GenericTransactionFlow(TransactionFlowOption.Allowed)]

    IAsyncResult BeginProcessRequest(Zpráva, zpětné volání AsyncCallback,

        stav objektu);

    Message EndProcessRequest(IAsyncResult result);

}

Výše uvedená konfigurace koncového bodu zveřejňuje koncové body směrování, které mají uživatelé používat.  Klientské aplikace si vyberou jeden z těchto koncových bodů, které se mají použít v rámci kódu klienta, a všechny vyvolání služby budou směrovat přímo do služby RoutingService. Když služba RoutingService přijme zprávu prostřednictvím jednoho z těchto koncových bodů, vyhodnotí filtry směrovacích zpráv a určí, kam zprávu přeposlat.

Konfigurace služby RoutingService s filtry zpráv

Službu RoutingService můžete nakonfigurovat pomocí filtrů zpráv prostřednictvím kódu nebo konfigurace (stejně jako všechno ostatní ve WCF). WCF 4 poskytuje RoutingBehavior pro správu filtrů zpráv směrování. Nejprve musíte povolit RoutingBehavior ve routerService a pak zadat název tabulky filtru, kterou chcete použít s touto konkrétní instancí RoutingService:

> konfigurace <

  <system.serviceModel>

    ...

    <chování>

      <serviceBehaviors>

        <behavior name="routingData">

          <serviceMetadata httpGetEnabled="True"/>

          <!-- Definujte chování směrování a zadejte název tabulky filtru –>

          <routing filterTableName="filterTable1" />

        </behavior>

      </serviceBehaviors>

    </behaviors>

    ...

Pokud se podíváte na předchozí příklad, kde jsme nakonfigurovali službu RoutingService s koncovými body, uvidíte, že jsme pro službu použili chování routingData prostřednictvím atributu behaviorConfiguration. Dále musíme definovat tabulku filtru s názvem "filterTable1".

Než ale můžeme definovat tabulku filtrů, potřebujeme definice koncových bodů pro cílové služby, do kterých chceme směrovat. Tyto cílové koncové body definujete v části konfigurace klienta WCF <>>, protože služba RoutingService je v podstatě "klient" při předávání zpráv cílové službě. Následující příklad ukazuje, jak definovat dva cílové koncové body, na které můžeme směrovat:

> konfigurace <

    ...

    <!-- Definujte koncové body klienta, se kterými chceme směrovač komunikovat.

         Jedná se o cíle, kterým směrovač bude odesílat zprávy. ->

    > klienta <

      <název koncového bodu="CalculatorService1"

       address="https://localhost:8000/servicemodelsamples/calcservice1"

       binding="wsHttpBinding" contract="*" />

      <název koncového bodu="CalculatorService2"

       address="https://localhost:8001/servicemodelsamples/calcservice2"

       binding="wsHttpBinding" contract="*" />

    </client>

    ...

Teď můžeme definovat skutečnou tabulku filtrů, která určí logiku směrování za běhu. Položky tabulky filtru definujete v <filterTables> elementu. Každá položka v <filterTable> definuje mapování mezi směrováním "filtr" a cílovým koncovým bodem. Definujete "filtry", které chcete použít v rámci <filtrů> elementu – každý <filtr> položka určuje, jaký typ filtru chcete použít spolu s daty specifickými pro filtr (například hodnota akce, výraz XPath atd.).

Následující příklad ukazuje, jak nakonfigurovat tabulku filtru s jedním filtrem, který se mapuje na koncový bod CalculatorService1. V tomto případě filtr MatchAll odpovídá všem příchozím zprávům:

> konfigurace <

    ...

    <!--ROUŽENÍ ODDÍLu –>

    > směrování <

      <!-- Definujte filtry, které má směrovač používat. ->

      filtry <>

        <filter name="MatchAllFilter1" filterType="MatchAll" />

      </filters>

      <!-- Definujte tabulku filtru, která obsahuje filtr matchAll –>

      <filterTables>

        <filterTable name="filterTable1">

            <!-- namapovat filtr na koncový bod klienta, který byl dříve definován.

                 Zprávy odpovídající tomuto filtru budou odeslány do tohoto cíle. ->

          <přidat filterName="MatchAllFilter1" endpointName="CalculatorService1" />

        </filterTable>

      </filterTables>

    </routing>

  </system.serviceModel>

</configuration>

Správné fungování směrování můžeme ověřit spuštěním hostitelské aplikace směrovací služby, hostitelské aplikace CalculatorService1 a klienta, který je navržený tak, aby odesílal zprávy do jednoho z koncových bodů směrovače. Když spustíme klienta, měli bychom vidět, že zprávy přicházejí na CalculatorService 1 poté, co se "směrují" průběžnou službou RoutingService (viz obrázek 14, obrázek 15 a obrázek 16).

Obrázek 14: Hostitelská aplikace RoutingService

obrázek 15: Klient, který cílí na službu RoutingService na https://localhost:8000/routingservice/router

Obrázek 16: Cílová služba (CalculatorService1)

Filtry zpráv a směrování založené na obsahu

WCF obsahuje několik předdefinovaných tříd MessageFilter, které můžete použít ve spojení s filtry směrovacích zpráv ke kontrole obsahu příchozích zpráv.

WCF například poskytuje ActionMessageFilter, který umožňuje spárovat konkrétní WS-Addressing "action" hodnoty. WCF také poskytuje EndpointAddressMessageFilter, EndpointNameMessageFilter a PrefixEndpointAddressMessageFilter, které umožňují spárovat konkrétní podrobnosti koncového bodu. Jedním z nejflexibilnějších je XPathMessageFilter, který umožňuje vyhodnotit výrazy XPath vůči příchozím zprávám. Všechny tyto filtry umožňují provádět směrování na základě obsahu v rámci vašeho řešení.

Kromě těchto předdefinovaných typů MessageFilter umožňuje WCF 4 také definovat vlastní filtry zpráv, což je jeden z primárních bodů rozšiřitelnosti pro RoutingService.

Podívejme se na příklad směrování založeného na obsahu na základě hodnot akcí. Předpokládejme, že chceme směrovat polovinu operací CalculatorService na CalculatorService1 a druhou polovinu na CalculatorService2. Toho dosáhnete tak, že definujete filtry pro každou z různých hodnot akcí CalculatorService a namapujete polovinu z nich na každý koncový bod cílové služby, jak je znázorněno tady:

> konfigurace <

    ...

    <!--ROUŽENÍ ODDÍLu –>

    > směrování <

      <!-- Definujte filtry, které má směrovač používat. ->

     filtry <>

        <filter name="addFilter" filterType="Action"

         filterData="http://Microsoft.Samples.ServiceModel/ICalculator/Add"/>

         <filter name="subFilter" filterType="Action"

         filterData="http://Microsoft.Samples.ServiceModel/ICalculator/Subtract"/>

        <filter name="mulFilter" filterType="Action"

         filterData="http://Microsoft.Samples.ServiceModel/ICalculator/Multiply"/>

        <filter name="divFilter" filterType="Action"

         filterData="http://Microsoft.Samples.ServiceModel/ICalculator/Divide"/>

      </filters>

      <filterTables>

        <filterTable name="filterTable1">

          <přidat filterName="addFilter" endpointName="CalculatorService1"/>

          <přidat filterName="subFilter" endpointName="CalculatorService2"/>

          <přidat filterName="mulFilter" endpointName="CalculatorService1"/>

          <přidání filterName="divFilter" endpointName="CalculatorService2"/>

        </filterTable>

      </filterTables>

    </routing>

  </system.serviceModel>

</configuration>

Když teď spustíme řešení a spustíme klienta, který vyvolá všechny čtyři operace, v každém okně konzoly služby se zobrazí polovina operací (viz obrázek 17 a obrázek 18).

obrázek 17: Výstup CalculatorService1

obrázek 18: Výstup CalculatorService2

XPathMessageFilter poskytuje ještě větší flexibilitu, protože můžete zadat různé výrazy XPath pro vyhodnocení příchozích zpráv. Výrazy XPath mohou vyhodnotit libovolnou část příchozí zprávy, včetně hlaviček PROTOKOLU SOAP nebo textu PROTOKOLU SOAP. Díky tomu máte při vytváření filtrů zpráv založených na obsahu velkou flexibilitu. Aby bylo možné pochopit mechaniku XPathMessageFilter, následující ukazuje, jak přepsat poslední příklad pomocí výrazů XPath:

> konfigurace <

    ...

    <!--ROUŽENÍ ODDÍLu –>

    > směrování <

      <!-- Definujte filtry, které má směrovač používat. ->

     filtry <>

        <filter name="addFilter" filterType="XPath"

                filterData="/s:Envelope/s:Header/wsa:Action =

                'http://Microsoft.Samples.ServiceModel/ICalculator/Add''/>

        <filter name="subFilter" filterType="XPath"

                filterData="/s:Envelope/s:Header/wsa:Action =

                'http://Microsoft.Samples.ServiceModel/ICalculator/Subtract''/>

        <filter name="mulFilter" filterType="XPath"

                filterData="/s:Envelope/s:Header/wsa:Action =

                'http://Microsoft.Samples.ServiceModel/ICalculator/Multiply''/>

        <filter name="divFilter" filterType="XPath"

                filterData="/s:Envelope/s:Header/wsa:Action =

                'http://Microsoft.Samples.ServiceModel/ICalculator/Divide''/>

      </filters>

      <namespaceTable>

        <add prefix="s" namespace="http://www.w3.org/2003/05/soap-envelope" />

        <add prefix="wsa" namespace="http://www.w3.org/2005/08/addressing" />

      </namespaceTable>

      <filterTables>

        <filterTable name="filterTable1">

          <přidat filterName="addFilter" endpointName="CalculatorService1"/>

          <přidat filterName="subFilter" endpointName="CalculatorService2"/>

           <přidat filterName="mulFilter" endpointName="CalculatorService1"/>

          <přidání filterName="divFilter" endpointName="CalculatorService2"/>

        </filterTable>

      </filterTables>

    </routing>

  </system.serviceModel>

</configuration>

Všimněte si, že atribut filterData obsahuje výraz XPath, který se vyhodnotí vůči příchozí zprávě (výrazy jednoduše zkontrolují hodnoty akcí v tomto příkladu). Všimněte si, jak jsem také definoval sadu vazeb předpon oboru názvů pomocí <namespaceTable> elementu. To je nezbytné, pokud chcete použít předpony oboru názvů v rámci výrazů XPath, jako jsem to udělal výše. Opětovné spuštění řešení s touto konfigurací vytvoří stejné výsledky jako předtím (viz obrázek 17 a obrázek 18).

Tuto techniku filtrování XPath budete muset použít pokaždé, když potřebujete směrovat zprávy na základě vlastních hlaviček SOAP nebo na základě obsahu nalezeného v textu zprávy SOAP.

Přemostění protokolu

V předchozích příkladech jsme ke komunikaci mezi klientem a směrovačem a mezi směrovačem a cílovými službami používali stejnou vazbu WCF (WSHttpBinding). Služba RoutingService dokáže přemostění komunikace napříč většinou vazeb WCF. Můžete například chtít nakonfigurovat směrovač tak, aby s ním klienti komunikovali přes WSHttpBinding, ale pak směrovač komunikuje s podřízenými cílovými službami pomocí NetTcpBinding nebo NetNamedPipeBinding.

Pojďme se podívat, jak nakonfigurovat službu RoutingService pro zpracování tohoto scénáře. Konfiguraci koncového bodu RoutingService ponecháme stejnou jako výše, která uživatelům umožňuje komunikovat se službou RoutingService přes BasicHttpBinding nebo WSHttpBinding. Teď ale změníme definice koncových bodů klienta pro cílové služby tak, aby používaly NetTcpBinding a NetNamedPipeBinding, jak je znázorněno tady:

> konfigurace <

    ...

    <!-- Definujte koncové body klienta, se kterými chceme směrovač komunikovat.

         Jedná se o cíle, kterým směrovač bude odesílat zprávy. ->

    > klienta <

      <název koncového bodu="CalculatorService1"

       address="net.tcp://localhost:8001/servicemodelsamples/calcservice1"

       binding="netTcpBinding" contract="*" />

      <název koncového bodu="CalculatorService2"

       address="net.pipe://localhost/servicemodelsamples/calcservice2"

       binding="netNamedPipeBinding" contract="*" />

    </client>

    ...

A samozřejmě budeme muset aktualizovat aplikace CalculatorService1 a CalculatorService2 tak, aby podporovaly kompatibilní koncové body NetTcpBinding a NetNamedPipeBinding. S touto konfigurací můžou uživatelé komunikovat se službou RoutingService pomocí BasicHttpBinding/WSHttpBinding a směrovač bude komunikovat s cílovými službami pomocí NetTcpBinding nebo NetNamedPipeBinding v závislosti na tom, do které služby se zpráva směruje.

Předání chyb a odolnost proti chybám

RoutingService také poskytuje integrovaný mechanismus, který řeší chyby komunikace za běhu a podporuje základní úroveň odolnosti proti chybám. Při definování tabulky filtrů můžete definovat různé seznamy alternativních koncových bodů, které bude služba RoutingService používat, pokud komunikace s počátečním cílovým koncovým bodem způsobí chybu. To v podstatě umožňuje mít seznamy koncových bodů zálohování.

Následující příklad ukazuje, jak definovat seznam koncových bodů zálohování v rámci elementu <backupLists>, který můžeme přidružit k položkám tabulky filtru:

> konfigurace <

    ...

    <!--ROUŽENÍ ODDÍLu –>

    > směrování <

      ... <!-- Definujte filtry, které má směrovač používat. ->

      <filterTables>

        <filterTable name="filterTable1">

          <přidání filterName="addFilter" endpointName="CalculatorService1"

               alternateEndpoints="backupEndpoints"/>

          <přidání filterName="subFilter" endpointName="CalculatorService1"

               alternateEndpoints="backupEndpoints"/>

          <add filterName="mulFilter" endpointName="CalculatorService1"

               alternateEndpoints="backupEndpoints"/>

          <přidání filterName="divFilter" endpointName="CalculatorService1"

               alternateEndpoints="backupEndpoints"/>

        </filterTable>

      </filterTables>

      < > backupLists

        <backupList name="backupEndpoints">

          <přidání endpointName="CalculatorService2"/>

        </backupList>

      </backupLists>

    </routing>

  </system.serviceModel>

</configuration>

Všimněte si, jak jsme v tomto příkladu nakonfigurovali všechny položky tabulky filtru tak, aby se předávaly na CalculatorService1, protože CalculatorService2 je teď náš koncový bod "zálohování", který se použije jenom v případě, že Výsledkem kalkulačkyService1 je výjimka TimeoutException, CommunicationException nebo odvozený typ výjimky. Pokud například řešení spustím znovu a zavřem CalculatorService1 a pak spustím klientský program, uvidíme všechny zprávy, které skončí ve službě CalculatorService2. Je důležité si znovu uvědomit, že veškerou tuto konfiguraci směrování je možné provádět dynamicky v kódu hostitelské aplikace.

Chování směrování vícesměrového vysílání

Služba RoutingService také podporuje automatické směrování konkrétní příchozí zprávy do více cílů pomocí "vícesměrového vysílání". Když příchozí zpráva odpovídá více filtrům nalezeným v nakonfigurované tabulce filtru, služba RoutingService automaticky směruje zprávu do každého cílového koncového bodu přidruženého k "odpovídajícím" filtrům.

Následující příklad ukazuje dvě položky směrování nakonfigurované se stejným filtrem zástupných znaků, který odpovídá všem příchozím zprávám:

> konfigurace <

    ...

    <!--ROUŽENÍ ODDÍLu –>

    > směrování <

      <!-- Definujte filtry, které má směrovač používat. ->

     filtry <>

        <filter name="wildcardFilter" filterType="MatchAll" />

      </filters>

      <filterTables>

        <filterTable name="filterTable1">

          <přidat filterName="wildcardFilter" endpointName="CalculatorService1"/>

          <přidat filterName="wildcardFilter" endpointName="CalculatorService2"/>

          <přidat filterName="wildcardFilter" endpointName="CalculatorService3"/>

        </filterTable>

      </filterTables>

    </routing>

  </system.serviceModel>

</configuration>

Při této konfiguraci se každá příchozí zpráva SOAP automaticky směruje do všech cílových koncových bodů bez ohledu na to, co se ve zprávách nachází.

Toto chování vícesměrového vysílání se skládá z možností přemostění protokolu a zpracování chyb probíraných v předchozích částech. Jediným problémem je, že u jednosměrné nebo duplexní komunikace funguje jenom jednosměrové nebo duplexní komunikace, ale ne komunikace s odpověďmi na požadavky, protože základní systém musí udržovat poměr 1:1 mezi odchozími požadavky a příchozími odpověďmi.

Vylepšená podpora REST

WCF 4 obsahuje několik nových funkcí, které jsou užitečné při vytváření služeb RESTful pomocí WCF.  Tato sada funkcí se teď označuje jako wcf WebHttp Services. Patří mezi ně podpora automatické stránky nápovědy popisující službu RESTful pro uživatele, zjednodušené ukládání do mezipaměti HTTP, výběr formátu zpráv, výjimky přívětivé k REST, integrace směrování ASP.NET, některé nové šablony projektů sady Visual Studio a další. Nebudeme mít prostor pro pokrytí všech těchto funkcí podrobně, ale dám vám rychlý úvod do několika mých oblíbených níže spolu s odkazy na další informace o zbytek.

Řada těchto funkcí byla poprvé představena sadou WCF REST Starter Kit v minulém roce a nyní ji zavádí do oficiální architektury. V budoucnu se může zobrazit více funkcí sady WCF REST Starter Kit.

Automatická stránka nápovědy

Při použití Třídy WebServiceHost ve WCF 4 budou vaše služby RESTful automaticky využívat výhody automatické funkce stránky nápovědy. Jedná se o mnohem potřebný doplněk při použití REST s ohledem na chybějící metadata WSDL a generování kódu na straně klienta – uživatelům je mnohem jednodušší zjistit, jak začít se službou – takže je obvykle vhodné tuto novou funkci povolit.

Když k hostování služby použijete třídu WebServiceHost, automaticky nakonfiguruje vaši službu pomocí WebHttpBehavioru a přidá výchozí koncový bod HTTP nakonfigurovaný pomocí Třídy WebHttpBinding (na základní adrese HTTP). Od WCF 4 je třída WebHttpBehavior dodávána s HelpEnabled vlastnost, která určuje, zda je nová stránka nápovědy povolena v rámci hostitele. Následující příklad konfigurace ukazuje, jak povolit funkci automatické stránky nápovědy pro konkrétní koncový bod REST:

> konfigurace <

  <system.serviceModel>

    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />

    <chování>

      <koncové bodyBehaviors>

        <behavior name="HelpBehavior">

          <webHttp helpEnabled="true" />

        </behavior>

      </endpointBehaviors>

    </behaviors>

    > služeb <

      <service name="CounterResource">

        <endpoint behaviorConfiguration="HelpBehavior"

                  binding="webHttpBinding"

                  contract="CounterResource" />

      </service>

    </services>

  </system.serviceModel>

</configuration>

Stránku nápovědy můžete zobrazit tak, že přejdete na základní adresu služby s připojenou nápovědou na konec adresy URL (viz obrázek 19).

Obrázek 19: Stránka automatické nápovědy pro služby RESTFul

Stránka nápovědy obsahuje popis jednotlivých operací s poznámkami [WebGet] nebo [WebInvoke] a pro každou z nich popisuje šablonu identifikátoru URI, podporovanou operaci HTTP a podporované formáty zpráv, v podstatě vše, co uživatel potřebuje vědět (viz obrázek 20). Můžete také poskytnout popis, který je pro jednotlivé operace popisnější, použitím atributu [Description].

Pro každou žádost nebo odpověď poskytuje stránka nápovědy také schéma XML a odpovídající ukázkovou instanci XML, kterou uživatelé mohou použít k integraci se službou. Příjemci mohou schéma použít ke generování odpovídajících serializovatelných typů na straně klienta nebo mohou jednoduše zkontrolovat ukázkový dokument XML a ručně určit, jak napsat příslušný kód zpracování XML. Oba přístupy jsou užitečné.

Obrázek 20: Stránka automatické nápovědy pro konkrétní operaci

Tato nová funkce stránky nápovědy automaticky zjišťuje vaše služby RESTful, což nakonec usnadňuje využívání ostatních služeb. Vaši uživatelé můžou zjistit návrh identifikátoru URI služby, podporované operace HTTP a formáty požadavků a odpovědí a váš popis bude vždy synchronizovat s kódem WCF – podobně jako to funguje s webovými službami ASP.NET.

Podpora ukládání do mezipaměti HTTP

Jednou z hlavních potenciálních výhod REST je ukládání do mezipaměti HTTP. Abyste si však mohli tuto výhodu uvědomit, musíte využít různé hlavičky http ukládání do mezipaměti ve zprávách požadavků a odpovědí. Můžete to provést v rámci operací služby WCF ručním přístupem k hlavičce požadavku/odpovědi prostřednictvím instance WebOperationContext, ale není to triviální správně.

Wcf 4 proto obsahuje jednodušší model pro řízení ukládání do mezipaměti prostřednictvím atributu [AspNetCacheProfile], který můžete deklarativním způsobem použít u operací GET. Tento atribut umožňuje zadat název profilu ASP.NET ukládání do mezipaměti pro každou operaci a na pozadí existuje inspektor ukládání do mezipaměti (CachingParameterInspector), který se stará o zpracování všech základních podrobností o ukládání do mezipaměti HTTP.

Implementace [AspNetCacheProfile] vychází ze standardního mechanismu ukládání výstupu do mezipaměti ASP.NET. Následující příklad ukazuje, jak použít atribut [AspNetCacheProfile] na operaci [WebGet]:

...

[AspNetCacheProfile("CacheFor60Seconds")]

[WebGet(UriTemplate=XmlItemTemplate)]

[OperationContract]

public Counter GetItemInXml()

{

    return HandleGet();

}

...

Na tomto místě budete muset definovat profil ASP.NET ukládání výstupu do mezipaměti s názvem CacheFor60Seconds v souboru web.config. Následující web.config ukazuje, jak to lze provést:

> konfigurace <

  <system.web>

    <ukládání do mezipaměti>

      <outputCacheSettings>

        <outputCacheProfiles>

          <add name="CacheFor60Seconds" duration="60" varyByParam="format" />

        </outputCacheProfiles>

      </outputCacheSettings>

    </ukládání do mezipaměti>

  </system.web>

  <system.serviceModel>

    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />

  </system.serviceModel>

</configuration>

Všimněte si, jak je profil ASP.NET ukládání do mezipaměti nastaven na ukládání výstupu do mezipaměti po dobu 60 sekund a je nakonfigurovaný tak, aby se mezipaměť měnila podle proměnné řetězce dotazu ve formátu. To je důležité, protože dotčená služba podporuje XML i JSON, které řídíte prostřednictvím proměnné formátu (např. "?format=json"). Služba musí ukládat odpovědi XML a JSON nezávisle na sobě.

Tento konfigurační soubor také ukazuje, jak povolit režim kompatibility ASP.NET, který je nutný, pokud chcete využívat různé ASP.NET funkce, jako je ukládání výstupu do mezipaměti.

Atribut [AspNetCacheProfile] usnadňuje použití ukládání do mezipaměti HTTP, aniž byste museli pracovat s hlavičkami mezipaměti HTTP přímo. Základní chování WCF se postará o vložení hlaviček HTTP Cache-Control, Date, Expires a Vary HTTP v odpovědi, které klienti můžou také využít k určení správné sémantiky ukládání do mezipaměti v budoucnu.

Výběr formátu zprávy

Pokud se podíváte zpět na obrázek 19, všimnete si, že služba CounterResource podporuje formáty XML i JSON pro operace GET, POST a PUT. To bylo možné od WCF 3.5 prostřednictvím vlastností RequestFormat a ResponseFormat nalezených v atributech [WebGet] a [WebInvoke].

Provedl jsem to ve službě CounterResource definováním samostatného kontraktu operace pro každou verzi – jednu pro verzi XML a druhou pro verzi JSON – jak je znázorněno zde:

...

[WebGet(UriTemplate="")]

[OperationContract]

public Counter GetItemInXml()

{

    return HandleGet();

}

[WebGet(UriTemplate = "?format=json", ResponseFormat=WebMessageFormat.Json)]

[OperationContract]

public Counter GetItemInJson()

{

    return HandleGet();

}

...

To bohužel znamená, že pro každou logickou operaci potřebujete dva kontrakty operací, pokud chcete podporovat formáty XML i JSON. V případě služby CounterResource jsem musel mít šest kontraktů operací pro podporu XML i JSON pro operace GET, POST a PUT.

WCF 4 usnadňuje zpracování tohoto scénáře tím, že poskytuje podporu automatického výběru formátu na základě hlaviček HTTP Accept, což je lepší způsob, jak to udělat. Dovolte mi vysvětlit, jak to funguje.

Nejprve potřebujeme pro každou logickou operaci jenom jeden kontrakt operace:

[WebGet(UriTemplate="")]

[OperationContract]

public Counter GetItem()

{

    return HandleGet();

}

Potom na standardním webHttpEndpointu provedeme automatický výběr formátu, jak je znázorněno tady:

> konfigurace <

  <system.serviceModel>

    <standardEndpoints>

      <webHttpEndpoint>

        <!-- se standardní koncový bod "" používá k automatickému vytvoření webového koncového bodu. ->

        <standardEndpoint name="" helpEnabled="true"

            automaticFormatSelectionEnabled="true"/>

      </webHttpEndpoint>

    </standardEndpoints>

  </system.serviceModel>

</configuration>

Díky tomu teď služba dokáže zpracovávat a vracet zprávy XML nebo JSON. Zjistí, jaký formát se má použít, a to tak, že nejprve zkontroluje hlavičku HTTP Accept, kterou najdete ve zprávě požadavku. Pokud to nepomůže, použije stejný formát zprávy jako zpráva požadavku za předpokladu, že se jedná o XML nebo JSON, jinak použije výchozí formát pro konkrétní operaci.

Teď je na klientovi, aby určil, který formát se má použít prostřednictvím hlaviček HTTP Content-Type a Accept. Hlavička Content-Type určuje formát ve zprávě požadavku, zatímco hlavička Accept indikuje, jaký formát klient přijímá zpět ze služby. Pokud například klient chce ze služby dostat JSON zpět, měl by v požadavku zadat následující hlavičku HTTP Accept:

Přijmout: application/json

To se dá snadno provést v libovolném programovacím modelu klienta HTTP a je to také snadné pomocí nástrojů, jako je Fiddler. Obrázek 21 ukazuje, jak pomocí Fiddleru získat JSON z naší nové a vylepšené služby.

obrázek 21: Načtení JSON pomocí hlavičky HTTP Accept

WCF 4 také poskytuje nová rozhraní API, která usnadňují explicitní zadání formátu zprávy za běhu. Následující kód ukazuje, jak můžeme operaci GetItem rozšířit napsáním kódu, který nejprve hledá parametr řetězce dotazu "format" a explicitně nastaví formát odpovědi odpovídajícím způsobem. Pokud nenajde parametr "format", bude jednoduše spoléhat na hlavičku Accept jako předtím.

[WebGet(UriTemplate="")]

[OperationContract]

public Counter GetItem()

{

    pokud byl zadán parametr řetězce dotazu formátu,

    nastavte formát odpovědi. Pokud taková

    Parametr řetězce dotazu existuje, použije se hlavička Accept.

    string formatQueryStringValue =

       WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters[

       "format"];

    if (!string). IsNullOrEmpty(formatQueryStringValue))

    {

        if (formatQueryStringValue.Equals("xml",

           System.StringComparison.OrdinalIgnoreCase))

        {

            WebOperationContext.Current.OutgoingResponse.Format = WebMessageFormat.Xml;

        }

        else if (formatQueryStringValue.Equals("json",

           System.StringComparison.OrdinalIgnoreCase))

        {

            WebOperationContext.Current.OutgoingResponse.Format = WebMessageFormat.Json;

        }

        jiný

        {

            vyvolá novou výjimku WebFaultException<řetězci>(řetězec). Format("Nepodporovaný formát '{0}'";

               formatQueryStringValue), HttpStatusCode.BadRequest);

        }

    }

    return HandleGet();

}

Díky těmto novým funkcím už nebudete muset pevně zakódovat typ formátu zprávy do kontraktů operací [WebGet] a [WebInvoke], jako jste to udělali ve WCF 3.5.

Zpracování chyb RESTful

Vzhledem k tomu, že služby RESTful nepoužívají protokol SOAP, už nemáte k dispozici standardní mechanismus selhání PROTOKOLU SOAP, který umožňuje automatické mapování mezi výjimkami rozhraní .NET a chybovými zprávami SOAP. Při vytváření služeb REST v WCF 3.5 jste museli ručně sestavit zprávu odpovědi HTTP pokaždé, když chcete přizpůsobit chybovou zprávu HTTP odeslanou zpět klientovi.

Ve WCF 4 najdete novou třídu s názvem WebFaultException<T>, která usnadňuje přenos "webových chyb" (např. chyb HTTP) zpět uživatelům. Funguje velmi podobně jako FaultException<T> wcf, ale můžete zadat stavový kód HTTP a typ podrobností, abyste mohli poskytnout další podrobnosti.

Následující příklad ukazuje, jak vrátit chybu HTTP 400 (Chybný požadavek), když uživatel určuje nepodporovaný typ formátu – jednoduše používám řetězec pro typ podrobností:

if (!string). IsNullOrEmpty(format))

{

    if (formát). Equals("xml"; System.StringComparison.OrdinalIgnoreCase))

    {

        WebOperationContext.Current.OutgoingResponse.Format = WebMessageFormat.Xml;

    }

    else if (formát. Equals("json"; System.StringComparison.OrdinalIgnoreCase))

    {

        WebOperationContext.Current.OutgoingResponse.Format = WebMessageFormat.Json;

    }

    jiný

    {

        vyvolá novou výjimku WebFaultException<řetězci>(řetězec). Format("Nepodporovaný formát '{0}'";

           format), HttpStatusCode.BadRequest);

    }

}

Díky této nové funkci je mnohem přirozenější vrátit standardní chybové zprávy HTTP jednoduše vyvoláním výjimek, jako obvykle ve službách založených na protokolu SOAP.

Integrace WCF s trasami ASP.NET

Mezi možnostmi směrování založenými na adrese URL, které se nacházejí ve WCF 4 a ASP.NET 4, existuje mnoho podobností. Oba umožňují provést stejnou věc – v podstatě mapovat šablony adres URL na metody ve třídách. Mezi těmito dvěma modely však existuje jeden významný rozdíl.

Přístup WCF 4 spojuje návrh šablony adresy URL do jedné třídy prostřednictvím atributů [WebGet] a [WebInvoke] použitých na definici třídy během vývoje. S tím, jak služba roste a vyvíjí se v průběhu času, může to vést k rozsáhlému monolitickému návrhu, který nelze zohlednit do menších bloků dat. Na druhou stranu ASP.NET 4 oddělí logiku směrování od definice cílové třídy, takže v případě potřeby můžete mapovat trasy služeb napříč mnoha definicemi tříd.

WCF 4 teď poskytuje možnost integrovat modul směrování ASP.NET se službami WCF 4, aby bylo možné využít výhod modelu směrování ASP.NET nad vašimi službami WCF.

Provedete to ve své metodě Global.asax RegisterRoutes tím, že využijete novou třídu ServiceRoute, která vám umožní namapovat ASP.NET trasu do třídy služby WCF:

private void RegisterRoutes()

{

   WebServiceHostFactory factory = new WebServiceHostFactory();

   RouteTable.Routes.Add(new ServiceRoute("Bookmarks", factory,

      typeof(BookmarkService)));

   RouteTable.Routes.Add(new ServiceRoute("Users", factory,

      typeof(UserService)));

}

Volám RouteTable.Routes.Add dvakrát pro přidání nových tras pro dvě různé třídy služby WCF. První trasa mapuje "/Bookmarks" na třídu BookmarkService, zatímco druhá trasa mapuje "/Users" na třídu UserService. Všimněte si, že obě trasy jsou nakonfigurované tak, aby používaly WebServiceHostFactory.

Když teď použijeme atributy [WebGet] a [WebInvoke] v definicích třídy služby WCF, použijeme relativní cesty a budou relativní vzhledem k ASP.NET trasy zadané zde.

Šablony projektů REST

Jednou z přehledných funkcí v sadě Visual Studio 2010 je Správce rozšíření, ke kterému máte přístup z nástrojů | Správce rozšíření. Správce rozšíření umožňuje Microsoftu a dalším třetím stranám integrovat nové šablony projektů, ovládací prvky a nástroje do prostředí sady Visual Studio 2010 jednoduchým kliknutím na tlačítko. Pro produktové týmy Microsoftu je to skvělé, protože umožňuje dodávat věci po RTM a přesto je zpřístupnit oficiálním rozšířením poskytovaným Microsoftem.

Pokud vyvoláte Správce rozšíření a rozbalíte uzel Šablony, najdete podřízený uzel s názvem WCF. Klikněte na WCF a měli byste vidět čtyři nové šablony služby REST WCF – jednu pro každou verzi .NET (3.5 vs. 4.0) a jednu pro jazyk (C# vs. VB.NET), jak je znázorněno na obrázku 22.

obrázek 22: Nové šablony projektů REST WCF v Správce rozšíření

Tyto nové šablony projektů můžete vybrat a stáhnout je do místní instalace sady Visual Studio 2010 a použít je jako jakýkoli jiný typ projektu. Nový typ projektu REST najdete v jazyce Visual C# | Web | Aplikace služby REST WCF (za předpokladu, že jste nainstalovali verzi jazyka C#).

Když ho použijete k vytvoření nového projektu, všimnete si, že aplikace služby WCF REST, kterou generuje, používá většinu nových funkcí WCF 4, které jsem v této části zvýraznila.

Další informace

Kromě toho, co jsme zde probrali, přináší WCF 4 několik pokročilejších funkcí REST a nová rozšíření rozhraní WCF API, která zjednodušují zpracování vlastních formátů zpráv (nikoli XML nebo JSON), vracení zobrazení založených na šablonách pomocí nové funkce T4, implementaci podpory podmíněného GET a ETag, implementaci optimistické souběžnosti a generování odchozích odkazů.

Další informace o všech těchtonovýchch službách (WCF 4) najdete na všech těchto nových funkcích WCF 4, včetně těch, které jsme zde neměli k dispozici, přejděte na blog koncového bodu .NET a vyhledejte položku Představení služeb WCF WebHttp v .NET 4. Tým poskytl důkladnou 12dílnou sérii blogů, která postupně prochází každou novou funkcí a jednou položkou blogu spolu s mnoha ukázkovými kódy a podrobnými pokyny.

Služby pracovních postupů

Jednou z oblastí funkcí, které obdržely největší pozornost v .NET 4, bylo "služby pracovních postupů". Společnost Microsoft intenzivně investovala do zlepšení integrace mezi WCF a WF, aby poskytovala bohatý a deklarativní programovací model pro vytváření široké škály aplikací.

Principy služeb pracovních postupů

WF poskytuje deklarativní programovací model, který zvýší úroveň abstrakce pro ty, kteří zapisují logiku. WF vám nakonec poskytne architekturu pro psaní vlastních jazyků definováním vlastní knihovny aktivit obchodní domény. Poté vám poskytne vizuální návrhář pro psaní těchto aktivit do programů a modul runtime, který ví, jak spravovat provádění těchto programů.

WF poskytuje obzvlášť dobrý model pro implementaci dlouhotrvajících aplikací, které potřebují čekat na výskyt různých typů externích událostí, jako je příjem zprávy z jiného systému. Jeho model trvalosti umožňuje efektivní využití systémových prostředků tím, že udržuje program v paměti pouze v paměti, když je skutečně spuštěný. Když program čeká na výskyt externí události, může být trvalý v databázi, čímž uvolní systémové prostředky, které používal.

obrázek 23: Služby pracovních postupů

Věc, která WF liší od jiných vývojových architektur, je to, že vám tyto funkce poskytuje a zároveň umožňuje programovat pomocí sekvenční programovací logiky řízení toku, která je obvykle pro vývojáře mnohem jednodušší číst a psát kód pochopit.

Pokud vytváříte služby WCF, které jsou dlouhodobě spuštěné, nebo můžete využít některé z dalších výhod, které jsem právě popsal, můžete služby WCF implementovat pomocí pracovního postupu WF. WF můžete použít ke koordinaci logiky využívání dalších externích služeb.

Obrázek 23 znázorňuje tyto koncepty.

I když to bylo možné od verze .NET 3.5, platforma .NET 4 výrazně zlepšila prostředí pro vývojáře a poskytovala některé potřebné funkce, které v .NET 3.5 chyběly.

Kombinací světů WCF a WF získáte to nejlepší z obou světů. Díky návrhářům WF získáte deklarativní programovací model, prostředí pro vývojáře, výkonný modul runtime pro správu dlouhotrvajících služeb a bohatou flexibilitu komunikace, kterou nabízí WCF.

Sestavení první služby pracovního postupu

Abychom vám poskytli představu o novém prostředí pro vývojáře služeb pracovních postupů, projdeme vás kompletním příkladem vytvoření pomocí .NET 4 a nového návrháře sady Visual Studio 2010.

Pokud otevřete Visual Studio 2010 a vyberete Soubor | Nový projekt najdete v šablonách WCF nový projekt pracovního postupu – nazývá se "Aplikace služby pracovního postupu WCF". Vyberu tuto šablonu projektu a pojmenuji ji "HelloWorldWorkflowService" a vytvořím nový projekt.

obrázek 24: Šablony projektů služby pracovních postupů sady Visual Studio 2010

Po vytvoření bude nový projekt jednoduše obsahovat dva soubory – soubor Service1.xamlx obsahující definici deklarativní služby pracovního postupu a soubor Web.config obsahující konfiguraci služby.

Jednou z nejzajímavějších věcí o novém modelu služeb pracovních postupů v .NET 4 je to, že v XAML lze definovat celou definici služby.   V našem novém projektu soubor Service1.xamlx obsahuje definici služby a implementace je jednoduše pracovní postup založený na JAZYCE XAML. Soubor Web.config obsahuje konfiguraci služby WCF – tady definujete koncové body a chování služby pracovního postupu.

Obrázek 25 ukazuje, jak návrhář sady Visual Studio 2010 vypadá pro soubor Service1.xamlx. Všimněte si, že se jedná pouze o standardního návrháře pracovních postupů, pouze v tomto konkrétním případě bude pracovní postup, který navrhujeme, sloužit jako implementace služby WCF. Klíčem k integraci této definice pracovního postupu se službou WCF je nový WorkflowServiceHost a sada aktivit zasílání zpráv WCF (viz panel nástrojů na obrázku 25).

Obrázek 25: Návrh služby pracovního postupu v sadě Visual Studio 2010

Služba kostra pracovního postupu poskytovaná touto šablonou projektu obsahuje aktivitu příjmu následovanou aktivitou Odeslat. Všimněte si, že aktivita Receive obsahuje vlastnost OperationName a je aktuálně nastavená na GetData. Má také vlastnost Content pro vazbu příchozí zprávy na místní proměnnou definovanou v rámci aktivity Sequence – v tomto případě se proměnná nazývá "data" a je typu Int32 (viz okno Proměnné pod službou návrhu pracovního postupu na obrázku 25).

Aktivita Příjem je také nakonfigurována pro aktivaci služby, což znamená, že příchozí zpráva může způsobit vytvoření nové instance pracovního postupu. Všimněte si, že vlastnost CanCreateInstance je zaškrtnutá v okně Properties napravo na obrázku 25).

Pojďme tuto službu pracovního postupu trochu přizpůsobit. Nejprve změním název souboru služby z Service1.xamlx na HelloWorld.xamlx. V dalším kroku změním název služby na "HelloWorldService" ve správném okně. V dalším kroku změním vlastnost OperationName aktivity receive na SayHello. Nakonec nadefinuju novou proměnnou s názvem personName typu String v rámci sekvence.

Potom vytvořím vazbu vlastnosti Content aktivity Receive na proměnnou personName, jak je znázorněno na obrázku 26. Dále vytvořím vazbu vlastnosti Content aktivity Send na řetězec ve formátu "hello {0}!" vložení proměnné personName do zástupného symbolu Pak uložím výsledný soubor Service1.xamlx.

Obrázek 26: Definování vlastnosti Obsahu pro aktivity Receive

V tomto okamžiku pokračujte a otevřete soubor HelloWorld.xamlx a zkontrolujte jeho obsah. Můžete to udělat tak, že kliknete pravým tlačítkem na soubor v Průzkumníku řešení a vyberete Otevřít v aplikaci... za ním následuje "Editor XML". Díky tomu se můžete podívat na nezpracovanou definici XAML pro službu. Je důležité si uvědomit, že definice XAML představuje úplnou implementaci služby. Neexistuje vůbec žádný kód jazyka C#.

V této ukázce budeme spoléhat na výchozí koncový bod HTTP a předpokládáme, že používáme standardní chování služby, které automaticky povolí metadata služby, takže nepotřebujeme žádnou konfiguraci WCF.

Teď jsme připraveni otestovat službu pracovního postupu založenou na XAML. To je stejně snadné jako stisknutí klávesy F5 v sadě Visual Studio 2010. Stisknutím klávesy F5 se služba pracovního postupu načte do vývojového serveru ASP.NET a způsobí, že se zobrazí testovací klient WCF. Testovací klient WCF se automaticky připojí ke službě pracovního postupu, stáhne metadata WSDL a umožní otestovat logiku služby pracovního postupu (viz obrázek 27).

obrázek 27: Testování služby pracovních postupů

To ukazuje, že infrastruktura služeb pracovních postupů dokáže dynamicky vytvořit definici WSDL pro službu kontrolou aktivit odesílání a příjmu používaných v definici pracovního postupu a typů zpráv, které odesílají a přijímají.

Tím se dokončí jednoduchý návod k vytvoření první deklarativní služby pracovního postupu v .NET 4. Viděli jsme, že implementace služby je definována zcela v JAZYCE XAML a že k modelování interakcí se zasíláním zpráv v rámci pracovního postupu používáte aktivity odesílání a přijímání. Také jsme viděli, že .NET 4 obsahuje podporu hostování souborů .xamlx, čímž se odstraňuje potřeba dalších souborů .svc. V následujících částech budeme pokračovat v podrobnějším zkoumání jednotlivých oblastí.

Hostování služeb pracovních postupů

.NET 4 obsahuje novou a vylepšenou infrastrukturu hostování pro služby pracovních postupů. Služby pracovních postupů můžete hostovat ve službě IIS/WAS nebo ve vlastních aplikacích pomocí Třídy WorkflowServiceHost. Infrastruktura hostování .NET 4 poskytuje nezbytné součásti pro správu dlouhotrvajících instancí pracovního postupu a pro korelaci zpráv, pokud máte spuštěných více instancí služby současně. .NET 4 také poskytuje standardní koncový bod řízení pracovního postupu pro vzdálenou správu instancí pracovního postupu.

Hostování ve službě IIS/ASP.NET

Jednoduchý příklad HelloWorldWorkflowService, který jsme si prošli v předchozí části, ukazuje, jak hostovat služby pracovních postupů ve službě IIS/ASP.NET. I když jsme službu otestovali pomocí vývojového serveru ASP.NET, fungovalo by to stejně ve službě IIS pomocí fondu aplikací ASP.NET 4. .NET 4 nainstaluje potřebnou obslužnou rutinu pro požadavky .xamlx, která zpracovává vytváření WorkflowServiceHost na pozadí a aktivaci jednotlivých instancí pracovního postupu.

I když jsme v našem prvním příkladu použili "nulovou konfiguraci", můžete nakonfigurovat služby pracovních postupů v rámci Web.config stejně jako jakoukoli jinou službu WCF. Tady byste nakonfigurovali všechny koncové body a chování WCF, které chcete použít. U služeb pracovních postupů můžete zveřejnit libovolný počet koncových bodů, ale měli byste zvážit použití jedné z nových vazeb kontextu (např. BasicHttpContextBinding, WSHttpContextBinding nebo NetTcpContextBinding), které spravují komunikaci specifickou pro instanci.

Následující příklad ukazuje, jak nakonfigurovat službu pracovního postupu se dvěma koncovými body HTTP:

> konfigurace <

  <system.serviceModel>

    > služeb <

      <service name="HelloWorldWorkflowService">

        <endpoint binding="basicHttpContextBinding" contract="IHelloWorld"/>

        <endpoint address="ws" binding="wsHttpContextBinding"

                  contract="IHelloWorld"/>

      </service>

      ...

Službu pracovního postupu můžete také nakonfigurovat s chováním WCF. Následující příklad ukazuje, jak nakonfigurovat tuto službu pracovního postupu s několika standardními chováními WCF:

> konfigurace <

  <system.serviceModel>

    > služeb <

      <service name="HelloWorldWorkflowService"

        behaviorConfiguration="HelloWorldWorkflowService.Service1Behavior" >

        <endpoint binding="basicHttpContextBinding" contract="IHelloWorld"/>

        <endpoint address="ws" binding="wsHttpContextBinding"

                  contract="IHelloWorld"/>

      </service>

     </services>

    <chování>

      <serviceBehaviors>

        <behavior name="HelloWorldWorkflowService.Service1Behavior">

          <serviceDebug includeExceptionDetailInFaults="False" />

          <serviceMetadata httpGetEnabled="True"/>

        </behavior>

      </serviceBehaviors>

      ...

Kromě těchto standardních chování WCF se .NET 4 dodává s některými novými chováními specifických pro WF pro řízení trvalosti pracovních postupů, sledování pracovních postupů a dalších chování modulu runtime pracovních postupů ve spojení se službami pracovních postupů. Další podrobnosti najdete v ukázkách sady .NET 4 SDK.

Samoobslužné hostování pomocí WorkflowServiceHost

I když byla .NET 3.5 součástí třídy WorkflowServiceHost pro hostování služeb pracovních postupů, bylo potřeba přepracovat všechny změny modulu runtime WF a programovacího modelu v .NET 4. Proto se rozhraní .NET 4 dodává s novou třídou WorkflowServiceHost, která se nachází v sestavení System.ServiceModel.Activities.

Třída WorkflowServiceHost usnadňuje hostování služeb pracovních postupů ve vaší vlastní aplikaci bez ohledu na to, zda se jedná o konzolovou aplikaci, aplikaci WPF nebo službu systému Windows. Následující fragment kódu ukazuje, jak používat WorkflowServiceHost v rámci vlastního kódu aplikace:

...

Hostitel WorkflowServiceHost = new WorkflowServiceHost("HelloWorld.xamlx";

    new Uri("https://localhost:8080/helloworld"));

hostitel. AddDefaultEndpoints();

hostitel. Description.Behaviors.Add(

    new ServiceMetadataBehavior { HttpGetEnabled = true });

hostitel. Open();

Console.WriteLine("Hostitel je otevřen");

Console.ReadLine();

...

Jak vidíte, bez ohledu na to, jestli se rozhodnete hostovat služby pracovních postupů ve službě IIS/ASP.NET nebo ve vlastních aplikacích, jsou stejně snadné jako všechny služby WCF.

WorkflowControlEndpoint

Hostování služby pracovního postupu se postará o inicializaci modulu runtime WF a aktivaci nových instancí pracovního postupu při aktivaci zpráv dorazí prostřednictvím jednoho z vystavených koncových bodů. Kromě této základní funkce hostování je také důležité spravovat konfiguraci a spouštění těchto spuštěných instancí pracovních postupů vzdáleně. .NET 4 to usnadňuje tím, že poskytuje standardní WorkflowControlEndpoint, který můžete zveřejnit ve službách pracovního postupu.

Následující příklad ukazuje, jak do služby přidat standardní koncový bod ovládacího prvku pracovního postupu ve vlastním scénáři hostování:

...

Hostitel WorkflowServiceHost = new WorkflowServiceHost("HelloWorld.xamlx";

    new Uri("https://localhost:8080/helloworld"));

hostitel. AddDefaultEndpoints();

WorkflowControlEndpoint wce = new WorkflowControlEndpoint(

    new NetNamedPipeBinding(),

    new EndpointAddress("net.pipe://localhost/helloworld/WCE"));

hostitel. AddServiceEndpoint(wce);

hostitel. Open();

...

Pokud hostujete ve službě IIS/ASP.NET, můžete standardní workflowControlEndpoint přidat následujícím způsobem:

> konfigurace <

  <system.serviceModel>

    > služeb <

      <service name="HelloWorldWorkflowService"

          behaviorConfiguration="HelloWorldWorkflowService.Service1Behavior" >

        <endpoint address="" binding="basicHttpContextBinding" contract="IHelloWorld"/>

        <endpoint address="ws" binding="wsHttpContextBinding" contract="IHelloWorld"/>

        <endpoint address="wce" binding="wsHttpBinding" kind="workflowControlEndpoint"/>

      </service>

      ...

WorkflowControlEndpoint umožní správu vaší služby pracovního postupu v různých hostitelských prostředích. Jedno takové prostředí je možné díky technologii Windows Server AppFabric, která bude dostupná v budoucí verzi Windows Serveru.

Aktivity odesílání a přijímání

.NET 3.5 obsahuje dvě aktivity zasílání zpráv – odesílání a přijímání – pro odesílání a příjem zpráv pomocí WCF, ale z hlediska jejich funkcí byly poměrně omezené. .NET 4 vylepšuje aktivity odesílání a přijímání pomocí některých dalších funkcí (např. korelace) a přidává několik dalších aktivit zasílání zpráv – SendReply a ReceiveReply – které zjednodušují modelování operací odpovědi na žádosti.

Když použijete aktivity odesílání a přijímání v rámci služby pracovního postupu, v podstatě je používáte k modelování kontraktu služby, který bude vystaven klientům prostřednictvím definice WSDL. Při použití aktivity Přijmout ji pojmenujete operaci a namapujete příchozí zprávu na typ .NET. I když zatím používáme jednoduché řetězce, můžete také použít složité uživatelsky definované datové kontrakty. Pojďme aktualizovat Službu HelloWorldWorkflowService tak, aby používala následující typ datového kontraktu:

[DataContract(Namespace="")]

public class Person

{

    [DataMember]

    ID veřejného řetězce;

    [DataMember]

    public string FirstName;

    [DataMember]

    public string LastName;

}

Pokud tuto definici třídy přidáme do webového projektu a vrátíme se do helloWorld.xamlx, můžeme definovat novou proměnnou s názvem personMsg typu Person (datový kontrakt definovaný výše). Pak můžeme namapovat jak aktivity ReceiveRequest, tak SendResponse na proměnnou personMsg prostřednictvím vlastnosti Content. Pokud to chcete udělat, jednoduše vyberte každou aktivitu a stisknutím tlačítka Obsah zobrazte okno Definice obsahu. Potom do textového pole Data zprávy a Do textového pole Typ zprávy zadejte "personMsg". Budete to muset udělat pro obě aktivity.

Aktivity Send/Receive také umožňují konfigurovat další aspekty služby WCF, jako je název operace, název kontraktu služby, akce, kolekce známých typů, úroveň ochrany a serializátor pro použití za běhu (např. DataContractSerializer vs. XmlSerializer). V aktivitě Odeslat také zadáte podrobnosti o cílovém koncovém bodu. Všechna tato nastavení se dají konfigurovat prostřednictvím okna Vlastnosti, pokud máte vybranou aktivitu Odesílání a přijímání.

S těmito změnami můžete znovu otestovat HelloWorld.xamlx, abyste viděli, že operace SayHello je nyní definována pro příjem a vracení zpráv typu Osoba.

Definování operací Request-Reply

Aby bylo možné modelovat operace odpovědi na žádosti, zavádí .NET 4 několik nových aktivit pro modelování těchto typů interakcí. Jednou je aktivita SendReply, kterou můžete kombinovat s aktivitou Příjmu za účelem implementace operace odpovědi na požadavek v rámci služby. Existuje také aktivita ReceiveReply, kterou můžete kombinovat s aktivitou Send při vyvolání externí služby v rámci pracovního postupu.

.NET 4 obsahuje také několik aktivit vyšší úrovně s názvem ReceiveAndSendReply a SendAndReceiveReply, které uvidíte v sadě nástrojů sady Visual Studio 2010. Tyto aktivity jednoduše vytváří příjem a odesílání pomocí SendReply/ReceiveReply a usnadňují jejich použití. Když je přetáhnete na návrhovou plochu pracovního postupu, uvidíte, že se rozbalí na sekvenci, která obsahuje aktivitu Odeslat nebo Přijmout následovanou příslušnou aktivitou "odpovědět".

Přidání odkazu na službu

Aby bylo používání externích služeb ještě jednodušší, visual Studio 2010 také poskytuje funkci Přidat odkaz na službu, která funguje tak, jak byste očekávali, s výjimkou generování definice třídy proxy klienta, která generuje sadu aktivit na straně klienta. Jakmile vyberete Přidat odkaz na službu a zadáte adresu definice WSDL, Visual Studio stáhne WSDL a vygeneruje vlastní aktivitu pro každou operaci nalezenou v definici WSDL.

Podívejme se na jednoduchý příklad. Předpokládejme, že existuje služba CalculatorService s operacemi sčítání, odčítání, násobení a dělení, které chceme použít z naší služby pracovního postupu. Můžeme jednoduše vybrat Přidat odkaz na službu a určit umístění definice CalculatorService WSDL, jak je znázorněno na obrázku 28.

obrázek 28: Přidání referenčního služby

Po stisknutí tlačítka OK přidáme odkaz na službu, Visual Studio stáhne definici WSDL a vygeneruje čtyři vlastní aktivity, které se zobrazí v sadě nástrojů. Nyní máte aktivity sčítání, odčítání, násobení a dělení, které se dají snadno použít v rámci pracovních postupů k vyvolání externí služby.

Korelace

Při sestavování systémů, které se skládají ze služeb dlouhotrvajících pracovních postupů, je běžné, že existuje mnoho instancí jedné služby pracovního postupu, která současně čeká na výskyt stejné události (např. čekání na doručení konkrétní zprávy před pokračováním). Problém s tímto scénářem spočívá v tom, že potřebujete způsob, jak korelovat příchozí zprávu se správnou instancí pracovního postupu. Obvykle způsob, jakým určíte správnou instanci pracovního postupu, je kontrola obsahu příchozí zprávy.

.NET 4 obsahuje sofistikovanou funkci korelace zpráv založenou na obsahu, kterou můžete použít ve spojení s aktivitami odesílání a přijímání, které jsme právě probrali. Implementace této funkce se týká toho, co se označuje jako "korelační popisovače", což je další nový koncept v .NET 4.

Abyste mohli začít používat korelaci, musíte nejprve definovat proměnnou pracovního postupu typu CorrelationHandle. Tuto proměnnou si můžete představit jako bod rendezvous pro připojení části dat ze (potenciálně) dvou různých zpráv (zpracovávaných dvěma různými aktivitami zasílání zpráv). Aktivity Send a Receive poskytují vlastnost CorrelationSWith pro zadání proměnné CorrelationHandle.

Aby bylo možné korelovat zprávy odesílané více aktivitami odesílání a přijímání, je nutné zadat stejný popisovač korelace napříč všemi aktivitami, které se mají účastnit korelace. Potom u každé aktivity nakonfigurujete klíč korelace, který se namapuje na zprávu zpracovávanou danou konkrétní aktivitou (například prvek SSN v jedné zprávě by mohl korelovat s prvkem CustomerId v jiné zprávě). Klíče korelace definujete pomocí výrazů XPath, které se vyhodnocují vůči zprávám.

Pojďme naši službu HelloWorldWorkflowService rozšířit a podívat se na příklad toho, jak to funguje. V současné době ukázka, se kterou pracujeme, obdrží zprávu Osoba a vrátí ji zpět klientovi. Pojďme přidat další aktivitu ReceiveAndSendReply těsně pod aktivitu SendResponse v dolní části pracovního postupu. Tímto způsobem přidáte sekvenci, která obsahuje další příjem následovaný jiným příkazem SendReply. Dám aktivitě Receive název operace "Finish" (Dokončit) a budeme vyžadovat, aby klient do zprávy Dokončení poskytl pozdrav, který použijeme k vytvoření konečné odpovědi s pozdravem.

Jinými slovy, klienti nejprve zavolají SayHello, aby zahajovali novou instanci služby pracovního postupu. Instance pracovního postupu pak počká, až klient zavolá dokončení poskytování pozdravu (a to může trvat minuty, hodiny nebo dny, během které může pracovní postup trvat). Jakmile klient zavolá dokončení zadání pozdravu, pracovní postup vytvoří pozdrav pomocí pozdravu a původního názvu a vrátí ho. V tomto scénáři můžeme snadno mít několik spuštěných instancí pracovního postupu, které čekají na zavolání operace Dokončení, takže určitě budeme muset korelovat zprávu Dokončení s předchozí zprávou SayHello. Vzhledem k tomu, že se jedná o tento případ, potřebuji přidružit aktivitu Receive pro "Finish" ke stejnému popisovači korelace, který jsme zadali v aktivitě "SayHello" (nameHandle).

Teď se podíváme na obsah zprávy, který budeme korelovat mezi těmito dvěma aktivitami. V tomto příkladu použijem k modelování zpráv následující dva typy datových kontraktů:

[DataContract(Namespace="")]

public class Person

{

    [DataMember]

    public string FirstName { get; set; }

    [DataMember]

    veřejný řetězec LastName { get; set; }

}

[DataContract(Namespace = "")]

public class Greeting

{

    [DataMember]

    veřejný řetězec Salutation { get; set; }

    [DataMember]

    public string NameKey { get; set; }

}

Aktivita Receive pro SayHello je nakonfigurována tak, aby používala zprávu Person (Osoba) a akce Receive pro "Finish" (Dokončit) je nakonfigurována tak, aby používala zprávu s pozdravem. Předpokládáme, že hodnota LastName je vždy jedinečná, abychom ji mohli použít jako jedinečnou hodnotu pro korelaci. Proto když klient odešle zprávu "Finish", musí zadat stejnou hodnotu LastName použitou v předchozí zprávě "SayHello".

Teď se podíváme, jak nakonfigurovat popisovač korelace tak, aby to nastavil. Už jsem definoval(a) proměnnou CorrelationHandle v sekvenci s názvem "handle". První věcí, kterou musíme udělat, je "inicializovat" popisovač korelace v rámci aktivity "SayHello" Receive. Proto vyberte aktivitu "SayHello" Receive a stiskněte tlačítko vedle textového pole "CorrelationInitializers".

Tady musíte v rozevíracím seznamu vybrat "Query correlation initializer" (Inicializátor korelace dotazu) a pak byste měli být schopni zvolit vlastnost LastName pro pole dotazu (mělo by se vytvořit výraz XPath sm:body()/xg0:Person/xg0:LastName, jak je znázorněno na obrázku 29).

Pak musíme určit, že aktivita "Finish" Receive (Dokončit) odpovídá stejnému popisovači. Vyberte aktivitu "Finish" Receive (Dokončit) a stiskněte tlačítko KorelaceOn. Pak zadejte popisovač pro popisovač KorelaceWith a pak jako pole dotazu vyberte NameKey (viz obrázek 30).

Obrázek 29: Definování korelačního klíče pro "SayHello"

Obrázek 30: Definování korelačního klíče pro Dokončení

To nakonec znamená, že element LastName ve zprávě Person musí odpovídat elementu NameKey ve zprávě Greeting ve dvou samostatných požadavcích. Na tomto místě bude infrastruktura pracovního postupu moct automaticky korelovat zprávy za nás a směrovat příchozí zprávy "Dokončit" do správné instance pracovního postupu (na základě "LastName/NameKey").

Konečná aktivita SendReply vrátí volajícímu následující formátovaný řetězec, včetně informací z původního souboru personMsg a nového "greetingMsg":

String.Format("{0}{1}{2}!",

   greetingMsg.Salutation, personMsg.FirstName, personMsg.LastName)

Otestuju funkci korelace pomocí testovacího klienta WCF a spustím několik instancí pracovního postupu tak, že několikrát zavolám SayHello s různými hodnotami FirstName a LastName. Potom bychom měli mít několik spuštěných instancí služby pracovního postupu. Teď můžeme volat operaci Dokončení určující jednu ze stejných hodnot LastName použitých v jedné ze zpráv SayHello a měli bychom vidět odpovídající hodnotu FirstName použitou v posledním pozdravu vráceném klientovi (viz obrázek 31).

To znázorňuje korelaci založenou na obsahu v akci, což je poutavá funkce služeb pracovních postupů, která je součástí .NET 4. Je důležité si uvědomit, že korelaci můžete provádět také na základě dat na úrovni kanálu a protokolu, jako jste to mohli udělat v .NET 3.5 (např. pomocí id instance kanálu nebo pracovního postupu). Korelace založená na obsahu je flexibilnější a sofistikovanější přístup, jak to samé udělat.

Obrázek 31: Testování příkladu korelace založeného na obsahu

To nám přináší konec pokrytí služeb pracovních postupů. V tomto dokumentu jsme dokázali poškrábat jenom povrch služeb pracovních postupů, ale další informace najdete v ukázkách sady .NET 4 SDK a v rostoucí dokumentaci MSDN, kterou najdete online. Jak vidíte, kombinace WCF a WF 4 otevírá dveře zcela novému vývojovému modelu pro vytváření deklarativních, dlouhotrvajících a asynchronních služeb, které mohou využívat nejlepší funkce, které obě architektury musí nabídnout.

Různé pokročilé funkce

Kromě všeho ostatního, o čem jsme mluvili v tomto dokumentu, obsahuje WCF 4 několik pokročilejších funkcí, které mohou být užitečné. Mezi tyto pokročilé funkce patří vylepšená podpora překladu typů prostřednictvím dataContractResolver, schopnost zpracovávat konkurenční uživatele front pomocí ReceiveContext, nového kodéru streamu bajtů a vysoce výkonné trasování trasování založeného na trasování trasování událostí pro Windows.

Rozlišení typů pomocí DataContractResolver

Ve WCF 3.x existuje funkce rozlišení typu, která se označuje jako "známé typy". Když při deserializaci serializátor narazí na instanci, která není stejného typu jako deklarovaný typ, zkontroluje seznam deklarovaných "známých typů" a zjistí, jaký typ se má použít. Jako autor služby můžete pomocí atributů [KnownType] nebo [ServiceKnownType] nebo [ServiceKnownType] a nadefinovat seznam možných nahrazení. Tato funkce se běžně používá k podpoře dědičnosti a polymorfismu.

Wcf 3.x bohužel neposkytuje snadný způsob, jak přepsat algoritmus mapování typů používaný dataContractSerializer při provádění tohoto typu dynamického rozlišení typu za běhu. Aby bylo možné tento problém vyřešit, WCF 4 poskytuje abstraktní DataContractResolver třídy, ze které můžete odvodit z implementace vlastního algoritmu překladu typů.  Následující informace ukazují, jak začít:

třída MyDataContractResolver : DataContractResolver

{

    sestavení;

    public MyDataContractResolver(sestavení sestavení)

    {

        this.assembly = assembly;

    }

    Používá se při deserializaci

    Umožňuje uživatelům mapovat název xsi:type na libovolný typ.

    public override Type ResolveName(string typeName, string typeNamespace,

        Type declaredType, DataContractResolver knownTypeResolver)

    {

        ... // implementujte mapování.

    }

    Používá se při serializaci.

    Mapuje libovolný typ na novou reprezentaci xsi:type.

    public override bool TryResolveType(Type type, Type declaredType,

        DataContractResolver knownTypeResolver, out XmlDictionaryString typeName,

        out XmlDictionaryString typeNamespace)

    {

        ... // implementujte mapování.

    }

}

Jakmile máte vlastní DataContractResolver implementovaný, můžete ho zadat do DataContractSerializer, jak je znázorněno zde:

DataContractSerializer dcs = new DataContractSerializer(

    typeof(Object), null, int. MaxValue, false, true, null,

    new MyDataContractResolver(assembly));

Když teď použijete tuto instanci DataContractSerializer k serializaci/deserialize objektů, vaše vlastní DataContractResolver bude volána k provedení vlastního rozlišení typu.

Pokud chcete vložit vlastní DataContractResolver do modulu runtime WCF na pozadí, budete muset napsat chování kontraktu WCF, které se připojí k DataContractSerializerOperationBehavior a přepíše výchozí překladač. Sada .NET 4 SDK obsahuje kompletní příklad, který ukazuje, jak toho dosáhnout prostřednictvím chování kontraktu a vlastního atributu s názvem [KnownAssembly].

Vlastní rozlišení typů může být užitečné, když chcete přepsat výchozí hodnoty DataContractSerializer, přesně určit, které typy se používají pro serializaci nebo dynamicky spravovat známé typy.

Zpracování zpráv zařazených do fronty pomocí receiveContext

Pomocí WCF 3.x můžete zaručit přesně jednou doručení zpráv při použití NetMsmqBinding pomocí transakčních front a zařazení operace služby WCF do transakce MSMQ. Pokud při zpracování zprávy dojde k vyvolání výjimek, WCF zajistí, že se zpráva neztratí tak, že zprávu vrátíte do fronty (může se vrátit do původní fronty, fronty jedových zpráv nebo fronty nedoručených zpráv v závislosti na konfiguraci).

I když je tato funkce důležitá, existuje několik problémů, na které lidé běžně narazí. Jedním z nich je, že transakce jsou nákladné a vytváří velké množství čtení a zápisu ve frontách, což představuje větší režii a složitost. Dalším problémem je, že neexistuje způsob, jak zajistit, aby stejná služba příště zpracuje zprávu z fronty (například neexistuje způsob, jak konkrétní službu "uzamknout" zprávu), což je záruka, kterou byste mohli chtít v určitých scénářích provést.

Aby bylo možné tyto problémy vyřešit, WCF 4 zavádí nové rozhraní API s názvem ReceiveContext pro zpracování zpráv ve frontě. S receiveContext může služba "zobrazit" zprávu ve frontě, aby ji začala zpracovávat, a pokud se něco nepovede a vyvolá se výjimka, zůstane ve frontě. Služby mohou také zprávy "uzamknout", aby bylo možné opakovat zpracování v pozdějším bodu v čase. ReceiveContext poskytuje mechanismus pro "dokončení" zprávy po jejím zpracování, aby ji bylo možné odebrat z fronty.

Tento přístup zjednodušuje práci na několika frontách, protože zprávy se už nepřečtou a znovu zapisují do front přes síť a jednotlivé zprávy se během zpracování nepřesunou mezi různými instancemi služby. Podívejme se na jednoduchý příklad, který ukazuje, jak funguje.

Následující příklad ukazuje, jak používat ReceiveContext ke zpracování zpráv přicházejících do fronty:

...

[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]

[ReceiveContextEnabled(ManualControl = true)]

public void CalculateProduct(int firstNumber, int secondNumber)

{

    ReceiveContext receiveContext;

    pokud (! ReceiveContext.TryGet(OperationContext.Current.IncomingMessageProperties,

         out receiveContext))

    {

        Console.WriteLine("ReceiveContext není v tomto počítači nainstalován/nalezen.");

        vrátit;

    }

    if ((firstNumber * secondNumber) % 2 == (receiveCount % 2))

    {

        receiveContext.Complete(TimeSpan.MaxValue);

        Console.WriteLine("{0} x {1} = {2}"; firstNumber; secondNumber;

            firstNumber * secondNumber);

    }

    jiný

    {

        receiveContext.Abandon(TimeSpan.MaxValue);

        Console.WriteLine("{0} & {1} nezpracoval", firstNumber, secondNumber);

    }

    receiveCount++;

}

...

Za předpokladu úspěšného průchodu zavoláme ReceiveContext.Complete, abychom dokončili zpracování zprávy, což způsobí, že se odebere z podkladové fronty. Jinak zavoláme Abandon, což ponechá zprávu ve frontě pro budoucí opakování. Sada .NET 4 SDK obsahuje kompletní ukázku, kterou můžete použít k podrobnějšímu prozkoumání této nové funkce.

Zjednodušení kódování pomocí ByteStreamMessageEncodingBindingElement

V některých scénářích zasílání zpráv jednoduše chcete přenášet "objekty blob" binárních dat bez jakéhokoli zabalení nebo dalšího zpracování. Pro zjednodušení tohoto scénáře přináší WCF 4 nový ByteStreamMessageEncodingBindingElement, který to dělá právě. Rozhraní .NET 4 bohužel neobsahuje novou vazbu pro tento kodér, takže budete muset vytvořit vlastní vazbu, abyste ji mohli využít.

Sada .NET 4 SDK obsahuje úplný příklad, který ukazuje, jak definovat vlastní vazbu, která používá ByteStreamMessageEncodingBindingElement prostřednictvím vlastní třídy vazeb. Jakmile budete mít novou třídu vazeb na místě, kodér bajtů streamu se velmi snadno používá s vašimi službami.

Vysoce výkonné trasování trasování pro Windows

WCF 4 také vylepšuje trasování a diagnostiku. WCF 4 teď využívá trasování trasování událostí pro Windows, což výrazně zlepšuje výkon trasování a poskytuje lepší integraci s dalšími souvisejícími technologiemi, jako jsou Windows Workflow Foundation, Windows Server AppFabric a různé technologie pro správu, které se nacházejí v systému Windows Server, a nabízí lepší model pro platformu.

V případě Trasování událostí pro Windows můžou poskytovatelé událostí zapisovat události do relací a relací volitelně tyto události do protokolu. Uživatelé můžou naslouchat událostem relace v reálném čase nebo tyto události číst z protokolu po faktu. Kontrolery Trasování událostí pro Windows zodpovídají za povolení nebo zakázání relací a přidružení poskytovatelů k relacím.

Sada .NET 4 SDK poskytuje jednoduchý příklad, který ukazuje, jak využít tuto novou vysoce výkonnou architekturu trasování ve spojení se službami WCF.

Závěr

WCF 4 přináší mnoho vylepšení a několik zcela nových funkcí, které řeší některé z nejběžnějších komunikačních scénářů. Wcf 4 se především snadněji používá prostřednictvím zjednodušeného konfiguračního modelu a lepší podpory běžných výchozích hodnot.

Kromě toho WCF 4 poskytuje prvotřídní podporu pro zjišťování a směrování služeb, což jsou běžné požadavky ve většině podnikových prostředí a velkých iniciativ SOA – tyto funkce samotné nastavují WCF kromě mnoha konkurenčních architektur. WCF 4 také zjednodušuje vývoj služeb založených na REST a poskytuje několik dalších pokročilejších funkcí WCF, které dnes řeší některé konkrétní body bolesti.

Kromě toho poskytuje WCF 4 sofistikovanou integraci s WF, aby poskytoval nový model pro vývoj deklarativních služeb pracovních postupů. Služby pracovních postupů umožňují vyvíjet dlouhotrvající a asynchronní služby, které využívají programovací model WF a základní modul runtime. Díky novým aktivitám založeným na WCF a podpoře návrháře, kterou najdete v sadě Visual Studio 2010, se tento nový programovací model stává prvotřídní možností pro vytváření služeb.

V .NET 4 světy WCF a WF se slučují dohromady, aby nabízely soudržný programovací model, který vám dává nejlepší oba světy, které je potřeba nabídnout. Další informace o novinkách ve WF 4 najdete v tématu Úvod vývojáře do Windows Workflow Foundation v .NET 4.

O autorovi

Aaron Skonnard je spoluautorem pluralsightu, poskytovatele školení Microsoftu nabízející kurzy řízené instruktorem i kurzy pro vývojáře .NET na vyžádání. V těchto dnech Aaron tráví většinu času nahráváním Pluralsight On-Demand! kurzy zaměřené na Cloud Computing, Windows Azure, WCF a REST. Aaron strávil roky psaním, mluvením a výukou profesionálních vývojářů po celém světě. Můžete ho kontaktovat v http://pluralsight.com/aaron a http://twitter.com/skonnard.

Další zdroje informací