Förenklad konfiguration med WCF 4

När jag med WCF 3.x väljer att generera en Proxy med hjälp av svcutil eller Add Service Reference i Visual Studio så läggs det till en hel del konfiguration i .config-filen. Mycket av denna information kan jag, som oftast, ta bort. Det som minst måste vara kvar är definitionerna av den adress, binding och det kontrakt som tjänsten jag skall konsumera använder - vilket kan rymmas på tre rader. Men även dessa tre rader konfiguration är något som jag upplever som hinder för många för att vilja ta till sig WCF.

En glädjande nyhet för alla, oavsett om du hoppat på WCF tåget eller inte, är att vi med WCF 4 inte behöver ha ens ett system.serviceModel element i vår .config-fil för att göra en tjänst åtkomlig för konsumtion. Det är lite som med XP Mode i Windows 7 - det finns ingen anledning längre att inte uppgradera.

Default Endpoints

Grunden till detta är något som kallas för Default Endpoints - baserat på mitt val av protokollschema bygger WCF-stacken upp mina Endpoints automatiskt.

Titta på nedan exempel. Förutom tjänstekontraktet MotorbikeService är detta allt som min applikation nu består av. Ingen app.config för att definiera tjänsten eller dess Endpoints , och allt jag behöver göra i koden är att ange de URI:er där jag vill ha tjänsten exponerad.

 static void Main(string[] args) {

    var host = new ServiceHost(typeof(MotorbikeService),
        new Uri("https://localhost:8080/bikeStore"),
        new Uri("net.tcp://localhost:8081/bikeStore"));
    host.Open();

    foreach (var endpoint in host.Description.Endpoints) {
        Console.WriteLine(string.Format("{0} - {1}", endpoint.Address, endpoint.Binding.Name));
    }

    Console.Read();
    host.Close();
}

När jag väljer att köra applikationen så ser vi också vilka Bindings WCF-stacken har valt åt mig, baserat på ändpunkternas protokollscheman.

BasicHttpBinding

Mappningarna mellan protokollschema och Binding är definierade i machine.config. Vill du t ex ändra standard Binding för http-schemat till en Binding med stöd för WS-* protokollen så kan du göra det på maskin nivå men också på applikationsnivå i app.config.

Nu, när jag går ifrån WCF:s standardkonventioner, behöver jag lägga till system.serviceModel-elementet i min app.config. Därefter ändrar jag mappningen från BasicHttpBinding till WS2007Binding i protocolMappings-elementet.

 <system.serviceModel>
  <!-- ändra default binding för http-schemat till ws2007HttpBinding -->
  <protocolMapping>
    <add scheme="http" binding="ws2007HttpBinding"/>
  </protocolMapping>
</system.serviceModel>

Kör jag applikationen igen så ser vi att WCF-stacken nu bygger upp en WS2007Binding åt mig istället.

WS2007Binding

Alla mina tjänster som är exponerade över en HTTP-Endpoint kommer nu att använda WS2007Binding:en med dess standardinställningar. För att göra justeringar i dessa standardinställningar behövde jag i WCF 3.x överrida dem med en explicit Binding-konfiguration per Endpoint. Med WCF 4 kan jag nu överrida standardinställningarna på en Binding genom att definiera en namnlös Binding-konfiguration.

 <system.serviceModel>
  <!-- ändra default binding för http-schemat till ws2007HttpBinding -->
  <protocolMapping>
    <add scheme="http" binding="ws2007HttpBinding"/>
  </protocolMapping>
  <bindings>
    <ws2007HttpBinding>
       <!-- flödande transaktioner som default -->
      <binding transactionFlow="true"/>
    </ws2007HttpBinding>
  </bindings>
</system.serviceModel>

Förenklad IIS hosting

För att husera WCF-tjänster i IIS:en så är vi vana vid att skapa en .svc-fil som pekar ut vilken tjänst som skall hantera förfrågan. Med WCF 3.x räckte det inte att skapa denna fil – vi var även tvungen att definiera minst en Endpoint i web.config. Detta är med WCF 4 historia - jag lägger dit min .svc-fil och är därmed klar att erbjuda tjänsten för konsumtion.

 <%@ ServiceHost Service="ByeAsmx.MotorbikeService" %>

Om du minns min förra artikel om WCF 4 så har jag nu också ett frestande val att lägga till system.serviceModel-elementet i web.config och därmed slopa .svc-filen.

 <system.serviceModel>
  <serviceHostingEnvironment>
    <serviceActivations>
      <add relativeAddress="/BikeStore" service="ByeAsmx.MotorbikeService"/>
    </serviceActivations>
  </serviceHostingEnvironment>
</system.serviceModel>

inge .svc

.svc-fil eller Address Activation för dina asmx-ersättare?

Exempelkod finns att ladda ned här.