1.13k likes | 1.29k Views
2006. Välkommen till Sommarkollo 2006 Windows Communication Foudnation. Windows Communication Foundation. Johan Lindfors. Agenda. Vad är WCF Programmera WCF Kontrakt ”Hostning” och uppträdanden Bindningar och metadata Andra koncept Migrering eller integration Monitorering Säkerhet
E N D
2006 Välkommen till Sommarkollo 2006 Windows Communication Foudnation
Windows Communication Foundation Johan Lindfors
Agenda • Vad är WCF • Programmera WCF • Kontrakt • ”Hostning” och uppträdanden • Bindningar och metadata • Andra koncept • Migrering eller integration • Monitorering • Säkerhet • Transaktioner • Köhantering
Hur ser det ut idag? J2EE Microsoft JAX-RPC ASMX / WSE RMI Remoting CORBA DCOM EJB Enterprise Services JMS System.Messaging Sockets Sockets
WCF byggstenar • Förenar teknikerna för distribuerad kommunikation • ”On-machine”, ”Cross-machine”, ”Cross-Internet” • Brett stöd för WS-* specifikationerna • Kompatibelt med existerande tekniker från Microsoft • Förenklar utvecklingen av löst kopplade tjänster • Konfigurationsbaserad kommunikation Enhetlig Interoperabilitet Tjänsteorienterat
Lite om generiska klasser • En samlingsklass för olika typer • Lagra instanser i strukturen • Hämta instanser public class Stack {object[] items; public void Push(object item){…} public object Pop(){…} } Stack stack = new Stack(); int i; string s = null; stack.Push(i); stack.Push(s); // Inkonsekvens i typer! string s = (string)stack.Pop(); //Paying for cast
Utan generiska klasser • Hur kul är det här egentligen? public class IntegerStack { int[] items; public void Push(int item){…} public int Pop(){…} } public class StringStack { string[] items; public void Push(string item){…} public string Pop(){…} }
Med generiska klasser • Mallen • Användningen public class Stack<T> //T är generisk typparameter { T[] items; public void Push(T item){…} public T Pop(){…} } Stack<int> integerStack = new Stack<int>(); integerStack.Push(1); Stack<string> stringStack = new Stack<string>(); stringStack.Push(“Hello, World!”);
Detaljer… • Flera typer vid definition • Använda aliaser • Begränsningar public class Point<X,Y>{…} Point<int,int> point = null; using IntegerPoint = Point<int,int>; IntegerPoint point = null; public class Stack<T> where T: IComparable public class Node<T> where T: new() { private T item = new T(); }
Mer detaljer… • Kan bara konvertera typparametrar till ”interface” • Ärva från en generisk klass class MyClass<T> { void SomeMethod(T t) { ISomeInterface something = (ISomeInterface)t; SomeClass somethingElse = (SomeClass)t; //Error! } } public BaseClass<T>{…} public ChildClass: BaseClass<string> {…}
Mer detaljer… • Generiska metoder public class MyClass { public void MyMethod<T>(T t) { … } } MyClass instance = new MyClass(); instance.MyMethod(3); instance.MyMethod(“Hello, World”);
Klienter och tjänster Klient Tjänst
“Endpoints” • Endpoints exponerar funktionalitet Klient Tjänst Endpoint Endpoint Endpoint Endpoint
Adress, Bindning, Kontrakt • Endpoints exponerar funktionalitet • Adress beskriver VART! • Bindning beskriver HUR! • Kontrakt beskriver VAD! Klient Tjänst A B C C B A A B C A B C
Metadata • Endpoints exponerar funktionalitet • Adress beskriver VART! • Bindning beskriver HUR! • Kontrakt beskriver VAD! • WSDL beskriver ”endpoints” WSDL Klient Tjänst A B C C B A A B C A B C
Uppträdanden • Uppträdanden beskriver exempelvis • Instansiering och aktivering • Sessionshantering • Transaktioner WSDL Klient Tjänst A B C C B A A B C A B C U U U
Definition av kontrakt och tjänst • Kontrakt • Implementation [ServiceContract] public interface IHello { [OperationContract] string Hello(string name); } public class HelloService : IHello { public string Hello(string name) { return "Hello, " + name; } }
Hostning av tjänsten • I en egen applikation • IIS/WAS (http://localhost/HelloService/HelloService.svc) class HelloHost { static void Main(string[] args) { ServiceHost host = new ServiceHost(typeof(HelloService)); host.Open(); // Wait until done accepting connections Console.ReadLine(); host.Close(); } } <%@ ServiceHost Language=“C#” Service=“HelloService” %>
Konfiguration <?xmlversion="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <services> <servicename="HelloService"> <endpoint address="http://localhost/HelloService" binding="basicHttpBinding" contract="IHello" /> </service> </services> </system.serviceModel> </configuration>
Implementera klienten • Kod • Konfiguration static void Main(){ IHello proxy =new ChannelFactory<IHello>("HelloEndpoint").CreateChannel(); string r = proxy.Hello("Beat"); Console.WriteLine(r); } <system.serviceModel> <client> <endpointname="HelloEndpoint" address="http://localhost/HelloService" binding="basicHttpBinding" contract="IHello" /> </client> </system.serviceModel>
Agenda • Vad är WCF • Programmera WCF • Kontrakt • ”Hostning” och uppträdanden • Bindningar och metadata • Andra koncept • Migrering eller integration • Monitorering • Säkerhet • Transaktioner • Köhantering
Kontrakt • Strukturella – ”Structural” • [DataContract] • [MessageContract] • Agerande – ”Behavioral” • [ServiceContract] • [OperationContract] • [FaultContract]
[DataContract] • Oberoende av OO-åtkomstnivåer using System.Runtime.Serialization; [DataContract(Name="PersonType")] public class Person{ [DataMember] public string name; [DataMember(Name="AgeProperty")] private int age; [DataMember] float salary; int positionCode; }
[DataContract] • Hantering av samlingar [DataContract] public class LibraryCatalog { [DataMember] System.Collections.Hashtable catalog; }
[DataContract] • Använda [KnownType]-attributet [DataContract] [KnownType(typeof(Book))] [KnownType(typeof(Magazine))] public class LibraryCatalog { [DataMember] System.Collections.Hashtable catalog; } [DataContract] public class Book{…} [DataContract] public class Magazine{…}
[DataContract] • Vid osäkerhet av datatyper [DataContract] [KnownType(typeof(Book))] [KnownType(typeof(Magazine))] public class PublishedItem { [DataMember] object catalog; [DataMember] DateTime publicationDate; } [DataContract] public class Book{…} [DataContract] public class Magazine{…}
[DataContract] • Versionshantering [DataContract] public class Car { [DataMember(IsRequired = true)] public string Model; [DataMember(IsRequired = false)] //default public int HorsePower; }
[MessageContract] • För skräddarsydda ”SOAP-headers” • Vilket inte rekommenderas [DataContract] public class PurchaseOrder{...} [MessageContract] public class PurchaseOrderMessage { [MessageHeader] public int Number; [MessageBody(Order = 1)] public PurchaseOrder Order; }
[ServiceContract] • Kontrollerar hur strukturella kontrakt serialiseras [ServiceContract] [DataContractFormat(Style=OperationFormatStyle.Document)] //Or Rpc public interface IOrderEntry{...} [ServiceContract] [XmlSerializerFormat(Style=OperationFormatStyle.Document, Use=OperationFormatUse.Literal)] //Or Encoded public interface IOrderEntry{...}
[ServiceContract] • Duplex [ServiceContract(Session = true, CallbackContract = typeof(IOrderEntryCallback))] public interface IOrderEntry { [OperationContract(IsOneWay = true)] void PlaceOrder(PurchaseOrder order); } [ServiceContract] public interface IOrderEntryCallback { [OperationContract(IsOneWay = true)] void PlaceOrderCompleted(PurchaseOrderStatus orderStatus); }
[ServiceContract] • Implementation • En implementation av ett interface • Klassen kallas då ”Service Type” [ServiceContract] public interface IOrderEntry{ [OperationContract(IsOneWay = true)] void PlaceOrder(PurchaseOrder order); } internal class OrderEntryService : IOrderEntry { void IOrderEntry.PlaceOrder(PurchaseOrder order) { //Your code goes here } }
[OperationContract] • Exponera metoder • Egenskapen ”Action” [ServiceContract] public interface IOrderEntry { [OperationContract(IsOneWay=true)] void PlaceOrder(PurchaseOrderorder); } [ServiceContract] public interface IOrderEntry { [OperationContract( Action="http://contoso.com/GetOrder", ReplyAction="http://contoso.com/GetOrderReply")] PurchaseOrder GetOrder(String orderIdentifier); }
[OperationContract] • Rekommendation • Använd Action=”*” som en generell funktion [ServiceContract] public interface MyContract{ [OperationContract(IsOneWay = true, Action="urn:crud:insert")] void ProcessInsertMessage(Message message); [OperationContract(IsOneWay = true, Action="urn:crud:update")] void ProcessUpdateMessage(Message message); [OperationContract(IsOneWay = true, Action="urn:crud:delete")] void ProcessDeleteMessage(Message message); [OperationContract(IsOneWay = true, Action="*")] void ProcessUnrecognizedMessage(Message message); }
[OperationContract] • Synkront • Asynkront [ServiceContract] public interface IMath { [OperationContract] int Add(int I, int j); } [ServiceContract] public interface IMath { [OperationContract(AsyncPattern = true)] IAsyncResult BeginAdd(int i, int j, AsyncCallback cb, object o); int EndAdd(IAsyncResult result); }
[FaultContract] [DataContract] class MyFault{ [DataMember] public string Reason = null; } [ServiceContract] public interface IOrderEntry{ [OperationContract] [FaultContract(typeof(MyFault))] PurchaseOrder GetOrder(String orderId); } public class OrderEntry: IOrderEntry{ public PurchaseOrder GetOrder(string orderId){ try{…} catch(Exception exception) { MyFault theFault = new MyFault(); theFault.Reason = “Some Reason”; throw new FaultException<MyFault>(theFault);} } }
[FaultContract] • På klienten [DataContract(Name="MyFault")] public class ClientFault { [DataMember] string Reason = null; } ... try{ PurchaseOrder order = Service.GetOrder(orderId); } catch (FaultException<ClientFault> clientFault){ Console.WriteLine(clientFault.Detail.Reason); }
Programmera kontrakt • Kod först • Kontrakt först [ServiceContract] public class OrderEntry{ [OperationContract(IsOneWay = true)] public void PlaceOrder(PurchaseOrder order){ return; } } [ServiceContract] public interface IOrderEntry{ [OperationContract(IsOneWay = true)] void PlaceOrder(PurchaseOrder order); } public class OrderEntry : IOrderEntry{ public void PlaceOrder(PurchaseOrder order) { return; } }
WCF och WSDL • WSDL kontrakt genereras i flera filer • Använder <wsdl:import.../> • Scheman separeras alltid från tjänsten • <wsdl:definitions> • <wsdl:portType.../> • <wsdl:binding.../> • <wsdl:service.../> [ServiceContract(Namespace="urn:gadgets-org")] publicinterfaceMyServiceContract {} <endpointname="MyServiceEndpoint" bindingNamespace="http://myservice.com/binding" [ServiceBehavior(Namespace="urn:my-unique-namespace2")] public class MyService : IMyService
Agenda • Vad är WCF • Programmera WCF • Kontrakt • ”Hostning” och uppträdanden • Bindningar och metadata • Andra koncept • Migrering eller integration • Monitorering • Säkerhet • Transaktioner • Köhantering
Hosting - Implementation • I egna applikationer [ServiceContract] public interface ILenderService {...} internal class LenderService: ILenderService {...} public class Program { static void Main(string[] args) { using (ServiceHost host = ServiceHost( typeof(LenderService))) { host.Open(); Console.WriteLine(”Host is active."); Console.ReadLine(); host.Close(); } } }
Hosting - Implementation • I hanterad ”Windows Service” • Processens livslängd kontrolleras av OS • Inbyggd “Service Control Manager” public partial class MyNTService : ServiceBase{ private ServiceHost host = null; public MyNTService() { InitializeComponent(); } protected override void OnStart(string[] args){ this.host = new ServiceHost(typeof(LenderService)); host.Open(); } protected override void OnStop(){ host.Close(); } }
Hosting - Implementation • IIS 5.1 och 6 • Bara över HTTP • Med WAS • HTTP, TCP, NamedPipes using System.ServiceModel; namespace MyNamespace { [ServiceContract] public interface ILender {…} internal class LenderService: ILender {…} } <%@ ServiceHost Language=“C#” Service=“MyNamespace.LenderService” %>
Uppträdanden • Vid utveckling • Instansiering • ”Concurrency” • ”Throttling” • ”Transactions” • Vid driftsättning
Instansiering • .PerCall • En instans per anrop • .PerSession, .Shareable • En instans per session • .Single • En instans per tjänst [ServiceContract]public interface IEcho{ … } [ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)] internal class MyService: IEcho{ … }
Instansiering • .Single • Med ytterligare konstruktorer [ServiceContract] public interface IEcho{ ... } [ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)] internal class MyService: IEcho{private string myData = null; private MyService(){} internal MyService(string startUpData){this.myData=startUpData;} ... } public class MyHost{MyService service = new MyService(“The initial data”); using(ServiceHost host = new ServiceHost(service)){ ...} }
Instansiering • .PerSession [ServiceContract] [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)] public class Math { private long sum = 0; [OperationContract] public int Add(int i, int j) { this.sum = this.sum + i + j; return i + j; } [OperationContract] public long GetTotal() { return this.sum; } [OperationContract] [OperationBehavior(ReleaseInstanceMode = ReleaseInstanceMode.AfterCall)] public void Clear() { this.sum = 0; } }
“Concurrency” • Kontrollerar trådsäkerhet för ”Service Type” med tre lägen • Single (som är grundinställning) • Multiple • Reentrant • Inte relevant för instansering per anrop [ServiceContract] public interface IEchoContract{ ... } [ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Multiple)] public class EchoService: IEchoContract{ ... }
“Throttling” • Kan användas för att begränsa last • Samtidiga anrop, instanser, kopplingar [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)] public class MyService { ... } <behaviors> <behavior> <throttlingmaxConcurrentCalls="2" maxConnections="10" maxInstances="10"/> </behavior> </behaviors>
Agenda • Vad är WCF • Programmera WCF • Kontrakt • ”Hostning” och uppträdanden • Bindningar och metadata • Andra koncept • Migrering eller integration • Monitorering • Säkerhet • Transaktioner • Köhantering