1 Välkommen till Sommarkollo 2006 Windows Communication Foudnation 2006
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? Remoting ASMX / WSE DCOM System.Messaging Enterprise Services Microsoft Sockets RMI JAX-RPC CORBA JMS EJB J2EE 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
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(){…} } Lite om generiska klasser 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
Hur kul är det här egentligen? public class IntegerStack { int[] items; public void Push(int item){…} public int Pop(){…} } Utan generiska klasser public class StringStack { string[] items; public void Push(string item){…} public string Pop(){…} }
Mallen Användningen public class Stack //T är generisk typparameter { T[] items; public void Push(T item){…} public T Pop(){…} } Med generiska klasser Stack integerStack = new Stack (); integerStack.Push(1); Stack stringStack = new Stack (); stringStack.Push(“Hello, World!”);
Flera typer vid definition Använda aliaser Begränsningar public class Point {…} Point point = null; Detaljer… using IntegerPoint = Point ; IntegerPoint point = null; public class Stack where T: IComparable public class Node where T: new() { private T item = new T(); }
Kan bara konvertera typparametrar till ”interface” Ärva från en generisk klass class MyClass { void SomeMethod(T t) { ISomeInterface something = (ISomeInterface)t; SomeClass somethingElse = (SomeClass)t; //Error! } Mer detaljer… public BaseClass {…} public ChildClass: BaseClass {…}
Generiska metoder public class MyClass { public void MyMethod (T t) { … } MyClass instance = new MyClass(); instance.MyMethod(3); instance.MyMethod(“Hello, World”); Mer detaljer…
Klient Tjänst Klienter och tjänster
Klient Tjänst “Endpoints” Endpoint Endpoints exponerar funktionalitet
Klient Tjänst Adress, Bindning, Kontrakt A BC CBA CBA CBA Endpoints exponerar funktionalitet Adress beskriver VART! Bindning beskriver HUR! Kontrakt beskriver VAD!
WSDL Klient Tjänst Metadata A BC CBA CBA CBA Endpoints exponerar funktionalitet Adress beskriver VART! Bindning beskriver HUR! Kontrakt beskriver VAD! WSDL beskriver ”endpoints”
WSDL Klient Tjänst Uppträdanden Uppträdanden beskriver exempelvis Instansiering och aktivering Sessionshantering Transaktioner A BC CBA CBA CBA UUU
[ServiceContract] public interface IHello { [OperationContract] string Hello(string name); } Definition av kontrakt och tjänst public class HelloService : IHello { public string Hello(string name) { return "Hello, " + name; } Kontrakt Implementation
I en egen applikation IIS/WAS ( class HelloHost { static void Main(string[] args) { ServiceHost host = new ServiceHost(typeof(HelloService)); host.Open(); // Wait until done accepting connections Console.ReadLine(); host.Close(); } Hostning av tjänsten ServiceHost Language=“C#” Service=“HelloService” %>
Konfiguration <endpoint address=" binding="basicHttpBinding" contract="IHello" />
Kod Konfiguration static void Main() { IHello proxy = new ChannelFactory ("HelloEndpoint").CreateChannel(); string r = proxy.Hello("Beat"); Console.WriteLine(r); } Implementera klienten <endpoint name="HelloEndpoint" address=" binding="basicHttpBinding" contract="IHello" />
Arkitektur för dagen
Grundläggande
StoreService Vår samlingstjänst där allting händer
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]
Oberoende av OO-åtkomstnivåer [DataContract] 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; }
Hantering av samlingar [DataContract] public class LibraryCatalog { [DataMember] System.Collections.Hashtable catalog; }
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{…}
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{…}
Versionshantering [DataContract] public class Car { [DataMember(IsRequired = true)] public string Model; [DataMember(IsRequired = false)] //default public int HorsePower; }
Versionshantering, planera i förväg [DataContract] public class Person : IExtensibleDataObject { public virtual ExtensionDataObject UnknownData { get { return this.unknownData; } set { this.unknownData = value; } } [DataMember] public string fullName; private ExtensionDataObject unknownData; }
För skräddarsydda ”SOAP-headers” Vilket inte rekommenderas [MessageContract] [DataContract] public class PurchaseOrder {...} [MessageContract] public class PurchaseOrderMessage { [MessageHeader] public int Number; [MessageBody(Order = 1)] public PurchaseOrder Order; }
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 {...}
Duplex [ServiceContract] [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); }
Arv Används vid versionshantering Även vid flera kontrakt vid en ”endpoint” [ServiceContract] public interface IOrderEntry { [OperationContract(IsOneWay = true)] void PlaceOrder(PurchaseOrder order); } [ServiceContract] public interface IExtendedOrderEntry : IOrderEntry { [OperationContract] PurchaseOrder GetOrder(String orderIdentifier); }
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 }
Exponera metoder Egenskapen ”Action” [ServiceContract] public interface IOrderEntry { [OperationContract(IsOneWay = true)] void PlaceOrder(PurchaseOrder order); } [OperationContract] [ServiceContract] public interface IOrderEntry { [OperationContract( Action=" ReplyAction=" PurchaseOrder GetOrder(String orderIdentifier); }
Rekommendation Använd Action=”*” som en generell funktion [OperationContract] [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); }
Synkront Asynkront [ServiceContract] public interface IMath { [OperationContract] int Add(int I, int j); } [OperationContract] [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 (theFault); } }
På klienten [DataContract(Name="MyFault")] public class ClientFault { [DataMember] string Reason = null; }... try { PurchaseOrder order = Service.GetOrder(orderId); } catch (FaultException clientFault) { Console.WriteLine(clientFault.Detail.Reason); } [FaultContract]
Kod först Kontrakt först [ServiceContract] public class OrderEntry { [OperationContract(IsOneWay = true)] public void PlaceOrder(PurchaseOrder order) { return; } } Programmera kontrakt [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 Scheman separeras alltid från tjänsten <endpoint name="MyServiceEndpoint" bindingNamespace=" [ServiceContract(Namespace="urn:gadgets-org")] public interface MyServiceContract {} [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
I egna applikationer Hosting - Implementation [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(); }
I hanterad ”Windows Service” Processens livslängd kontrolleras av OS Inbyggd “Service Control Manager” Hosting - Implementation 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(); }
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 {…} } Hosting - Implementation ServiceHost Language=“C#” Service=“MyNamespace.LenderService” %>
Uppträdanden Vid utveckling Instansiering ”Concurrency” ”Throttling” ”Transactions” Vid driftsättning
.PerCall En instans per anrop.PerSession,.Shareable En instans per session.Single En instans per tjänst Instansiering [ServiceContract] public interface IEcho{ … } [ServiceBehavior(InstanceContextMode= InstanceContextMode.Single)] internal class MyService: IEcho { … }
.Single Med ytterligare konstruktorer Instansiering [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)) {... } }
.PerSession Instansiering [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; } }
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 “Concurrency” [ServiceContract] public interface IEchoContract {... } [ServiceBehavior(ConcurrencyMode= ConcurrencyMode.Multiple)] public class EchoService: IEchoContract {... }
Kan användas för att begränsa last Samtidiga anrop, instanser, kopplingar “Throttling” <throttling maxConcurrentCalls="2" maxConnections="10" maxInstances="10"/> [ServiceBehavior( ConcurrencyMode = ConcurrencyMode.Multiple)] public class MyService {... }
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
Bindningar En bindning består av Transport + ”Encoding” + Protokoll Tre sätt att konfigurera Använd en standard Anpassa en standard Skapa en skräddarsydd
Bindningar En bindning består av Transport + ”Encoding” + Protokoll Transport HTTP TCP NamedPipe MSMQ
”Encoding” Text För bästa interoperabilitet Binary För bästa prestanda WCF till WCF MTOM Message Transmission Optimization Protocol För att bifoga binära tillägg Använder XOP
MTOM ”Encoding” Implementation i WCF Välj helt enkelt MTOM som ”encoding” Alla byte[] och strömmar kommer att MTOM’as <binding name="MTOMBinding" messageEncoding="Mtom"/>
Protokoll Kan innehålla WS-Security WS-ReliableMessaging WS-Coordination och Transaction
Bindningar Interoperabiliet Säkerhet Session Transaktioner Duplex BasicHttpBindingBP 1.1T | S WsHttpBindingWST | SXX WsDualHttpBindingWSSXXX NetTcpBinding.NETT | SXXX NetNamedPipeBinding.NETTXXX NetMsmqBinding.NETT | SX CustomBinding***** T = SSL/TLS | S = WS-Security | O = “One-Way Only”
Att välja bindning BasicHttpBinding WsHttpBinding Interop? Nivå? Duplex? WSDualHttpBinding NetNamedPipeBinding NetMsmqBinding NetPeerTcpBinding NetTcpBinding Nej Basi c Nej Ja Lokalt? Köhantering? P2P? Nej Ja WS Ja
Bindningar: Standard <endpoint address=" binding="wsHttpBinding" contract="IMathService" /> OBS: Liten bokstav på bindning i konfiguration
Bindningar: Anpassa <endpoint address=” binding="wsHttpBinding" bindingConfiguration="MTOMOption" contract="IMath"/>
Definera i kod Bindningar: Skapa egna public static void Main(string[] args) { ServiceHost host = new ServiceHost(typeof(MathService), "net.tcp://localhost/8080/MathService/"); ReliableSessionBindingElement r = new ReliableSessionBindingElement(); r.AdvancedFlowControl = true; SecurityBindingElement s = AsymmetricSecurityBindingElement.CreateKerberosBinding(); TcpTransportBindingElement t = new TcpTransportBindingElement(); t.MaxMessageSize = long.MaxValue; BinaryMessageEncodingBindingElement e = new BinaryMessageEncodingBindingElement(); CustomBinding binding = new CustomBinding(new BindingElement[]{r,s,t,e}); EndpointAddress address = "net.tcp://localhost/8080/Math/"; host.AddEndpoint(typeof(IMath), binding, address); host.Open(); }
Definera i konfiguration Bindningar: Skapa egna
Adresser Adresser exponerar transportsätt net.tcp://x.se:8080/Service/MyEndPoint net.pipe://x.se/Service/MyEndPoint net.msmq://x.se/MyQueue
Per tjänst En basadress per transportsätt Per “Endpoint” Adressen är relativ till basadressen class Program { static void Main(string[] args) { using (ServiceHost host = new ServiceHost( typeof(EchoService), new Uri(" { host.Open(); Console.ReadLine(); host.Close(); } } } Adresser <endpoint address="Echo" binding="basicHttpBinding" contract="IEcho"/>
Hostning i IIS eller WAS Adressen är URL för.SVC fil Ex: Adresser <endpoint address="" binding="basicHttpBinding" contract="IEcho"/>
Med kod, metod 1 One-off “In-line Proxy” Klienter using System.ServiceModel; namespace MyNamespace { public interface IEcho { string Echo(string input); } public class Program { public static void Main(string[] arguments) { IEcho proxy = new ChannelFactory ("EchoService").CreateChannel(); Console.WriteLine(proxy.Echo(”Ping")); ((IChannel)proxy).Close(); }
Med kod, metod 2 Återanvändbar “klass-proxy” Klienter using System.ServiceModel; [ServiceContract] public interface IEchoService { [OperationContract] string Echo(string input); } internal class EchoServiceClient: ClientBase, IEchoService { public EchoServiceClient(string configurationName) :base(configurationName) { } string IEchoService.Echo(string input) { return this.InnerProxy.Echo(input); } public class Program { public static void Main(string[] arguments) { EchoServiceClient client = new EchoServiceClient("EchoService"); ((IEchoServiceClient)client).Echo("Hello, World!"); client.Close(); }
Konfigurationen Klienter <endpointname="EchoService" address=” binding="basicHttpBinding" contract="MyNamespace.IEcho"/>
Arkitektur för dagen Med Callback
IAdminService ”Callback”-funktionalitet
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
Migrering eller samexistens Sida-vid-sida Uppgradering Interoperabilitet
using System.Web.Services; public class AccountingOperation { public string AccountName; public long Amount; } public class Accounting { [WebMethod(TransactionOption=TransactionOption.RequiresNew)] public int AddEntry(AccountingOperation debit, AccountingOperation credit) { // Add entry to internal accounting book // return id. } } using System.ServiceModel; [ServiceContract(FormatMode=ContractFormatMode.XmlSerializer)] [OperationContract] [OperationBehavior(AutoEnlistTransaction=true)] // ASMX till WCF
public class Accounting : ServicedComponent { public void AddCreditEntry(string creditAccount, int creditAmount) { } using System.EnterpriseServices; [ComponentAccessControl] [SecureMethod] [Transaction(TransactionOption.Required)] [SecurityRole("Manager")] using System.ServiceModel; [ServiceContract] [OperationContract] [OperationBehavior(AutoEnlistTransaction=true)] [PrincipalPermission(SecurityAction.Demand, Role="Managers")] // COM+ till WCF
using Microsoft.Web.Services3; [WebService] class HelloWorld { [WebMethod] public string Hello (string text) { MessageSignature signature = (MessageSignature) RequestSoapContext.Current.Security.Elements[0]; if (!signature.SigningToken.Principal.IsInRole ("BUILTIN\Administrators")) throw new AuthorizationException("Access denied"); return String.Format("Hello, {0}", text); } } // Konfigurationsförändringar krävs också [OperationContract] [PrincipalPermission(SecurityAction.Demand, null, "BUILTIN\Administrators")] using System.ServiceModel; [ServiceContract] // WSE till WCF
class MyQService { public void ReceiveOrders() { MessageQueue Queue = new XmlMessageFormatter formatter = new XmlMessageFormatter( new Type[] { typeof(System.Data.DataSet)}); Queue.Formatter = formatter; System.Messaging.Message msg = null; while((msg= Queue.Receive()) != null) { DataSet booklist = (DataSet) msg.Body; ProcessOrders(booklist); } } Public void ProcessOrder(DataSet BookList) {... } } using System.Messaging; using System.ServiceModel; [ServiceContract] [OperationContract(IsOneWay = true)] // MSMQ till WCF
using System.Runtime.Remoting; [Serializable] public class AccountingOperation { public string AccountName; public long Amount; } public class Accounting { public int AddEntry(AccountingOperation debit, AccountingOperation credit) { // Add entry to internal accounting book // return id. } } using System.ServiceModel; [ServiceContract] [OperationContract] : MarshalByRefObject //.NET Remoting till WCF
Arkitektur för dagen Med integration
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
Monitorering Loggning Tracing Performance Counters Event Logging WMI
Loggning <messageLogging logEntireMessage="true" maxMessagesToLog="300" logMessagesAtServiceLevel="true" logMalformedMessages="true" logMessagesAtTransportLevel="false" />
Tracing Källor System.Security.Authorization Microsoft.InfoCards.Diagnostics System.IO.Log System.Runtime.Serialization System.ServiceModel Microsoft.TransactionsBridgs.Dtc Nivåer All, Off Critical, Error, Warning Information, Verbose ActivityTracing
Slå på räknare per service Kan sättas i machine.config Kan analyseras på fyra nivåer ServiceHost Endpoint Operation (AppDomain) “Performance Counters”
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
Säkerhet och WCF Säkerheten i WCF erbjuder två saker Säker överföring av meddelanden mellan entiteter Begränsa åtkomst till resurser från entiteter Entitet Person, företag, applikation Resurs Fil, tjänst, operation
Säkerhet för meddelanden Konfidentiell Integritet Autentisering Auktorisering Loggning
Vitsord – “Credentials” Utsagor – “Claims” Information om en entitet Används för att kontrollera åtkomst till resuser Utfärdare – “Issuer” Certifierar utsagor i vitsord Bevis på ägandeskap – ”Proof of possession” Hur en enitet bevisar sina utsagor
Säkerhetsmodellen i WCF Baseras på vitsord och utsagor Kan erbjuda önskade krav på säkerhet Säkert som grundinställning Utom vid interoperabilitet BasicHttpBinding Konsekvent mellan inställningar (bindningar) Konsekvent mellan vitsord
Scenarios för säkerhet
Säkerhet på transportnivå Säkerhetskraven erbjuds på transportlagret Fördelar Bra prestanda Vanlig implementation Små förändringar Nackdelar Begränsad uppsättning utsagor Ingen säkerhet utanför “tråden”
Säkerhet på transportnivå <endpoint address=" binding="basicHttpBinding" bindingConfiguration=”SSLBinding" contract="ICalculator" />
Säkerhet på meddelanden Säkerhetskraven erbjuds på meddelandelagret Fördelar Stöd för fler typer av utsagor Utbyggbart Säkerhet från “början till slut” Nackdelar Standards och användning konsolideras fortfarande Viss påverkan på prestandan
Säkerhet på meddelandenivå <endpoint address=" binding=”wsHttpBinding" bindingConfiguration=”WSBinding" contract="ICalculator" />
“Mixed Mode” Kompromiss mellan säkerhet på transport- och meddelande-nivån Transportnivån erbjuder integritet och konfidentiallitet Fördelar för prestandan Meddelandenivån hanterar utsagor Rika “vitsord”, utbyggbart
“Mixed Mode” <endpoint address=" binding=”wsHttpBinding" bindingConfiguration=”MixedBinding" contract="ICalculator" />
Användarnamn/lösenord Console.WriteLine(" Enter username[domain\\user]:"); string username = Console.ReadLine(); Console.WriteLine(" Enter password:"); string password = Console.ReadLine(); CalculatorProxy wsProxy = new CalculatorProxy(); wsProxy.ChannelFactory.Credentials. UserName.UserName = username; wsProxy.ChannelFactory.Credentials. UserName.Password = password;
“Impersonation” [OperationBehavior( Impersonation=ImpersonationOption.Required)] public double Sub(int a, int b) { return a - b; } public double Add(int a, int b) { using (ServiceSecurityContext.Current. WindowsIdentity.Impersonate()) { return a + b; }
“PrincipalPermission” [PrincipalPermission(SecurityAction.Demand, Role="Builtin\\Administrators")] public double Mul(int a, int b) { return a * b; }
Arkitektur för dagen Med säkerhet
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
Transaktioner Atomiska eller kompenserande Välj mellan koppling eller komplexitet Atomiska transaktioner Enklare att utveckla Negativ påverkan på prestandan “Tightare”-koppling Kompenserande aktivitet Mer komplex att utveckla Bättre prestanda “Lösare”-koppling Välj modell baserat på situationen
Transaktioner [ServiceContract] public interface IMyContract { [OperationContract] [TransactionFlow(TransactionFlowOption.Required)] bool Transfer1(Account from, Account to, decimal amount); [OperationContract] [TransactionFlow(TransactionFlowOption.NotAllowed)] bool Transfer2(Account from, Account to, decimal amount); } Delta i en transaktion
Transaktioner public class MyService: IMyContract { [OperationBehavior( TransactionScopeRequired = true, TransactionAutoComplete = true)] public bool Transfer1( Account from, Account to, decimal amount) {... } [OperationBehavior( TransactionScopeRequired = true, TransactionAutoComplete = false)] public bool Transfer2( Account from, Account to, decimal amount) {... OperationContext.Current.SetTransactionComplete(); } Utvecklaren av tjänsten
Transaktioner TransactionScope transaction; using (scope = new TransactionScope()) { proxyOne.Transfer1(AccountOne, AccountTwo, amount); proxyTwo.Transfer1(AccountThree,AccountFour,amount); UpdateLocalCache(AccountOne, AccountTwo, amount); scope.Complete(); } Använda transaktioner Klientsidan
Transaktioner <binding name="SampleBinding“ transactionFlow=“true" /> Kontroll av transaktioner Administratören av tjänsten
Arkitektur för dagen Transaktion
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 fungerar köer? Meddelande KlientTjänst “Queue”
Köer Förbättrar tillgängligheten Döljer åtkomst till tjänst eller nätverk Stöd för utskalning Flera läsare från en kö Erbjuder lastbalansering Buffrar meddelanden för senare hantering Är en av byggstenarna för kompenserande aktiviteter
Hur köer fungerar! Meddelande KlientTjänst “Dead Letter Queue” “Queue” “Poison Queue” “Queue”
“Queue Endpoint” <endpoint address ="net.msmq://MyServer/private/MyQueue/”" binding="netMsmqBinding" bindingConfiguration ="MyQueueBinding" contract="IPurchaseOrder" />
Arkitektur för dagen Med köhantering
Integrera med ASP.NET HttpContext.Current som i ASMX Värden måste vara IIS 5.1, 6 eller WAS Bara för transport över HTTP [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)] [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single)] internal class TallyService: ITally { long ITally.Tally(int value) { long? currentTally = (long?)HttpContext.Current.Session["Tally"]; if(currentTally == null)currentTally = 0; currentTally++; HttpContext.Current.Session["Tally"] = currentTally++; return currentTally; }
Integrera med ASP.NET Slå på i konfigurationen Web.config <service name="HostedService.TallyService, HostedService"> <endpoint address="" binding="basicHttpBinding" contract="HostedService.ITally, HostedService"/> <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
Integrera med ASP.NET På klientsidan <endpoint name="TallyService" address=" binding="customBinding” bindingConfiguration="AllowCookieBinding" contract="HostedService.ITally, Client"/>
“ASP.NET Providers” Medlemskap Existerar en användare? Har användaren specificerat korrekta “vitsord” Rollhantering Tillhör användaren en specifik grupp? Vilka grupper tillhör användaren?
RoleProvider public abstract class RoleProvider { public abstract void CreateRole(string roleName); public abstract bool DeleteRole(string roleName, bool throwOnPopulatedRole); public abstract bool RoleExsts(string roleName); public abstract string[] GetAllRoles(); public abstract void AddUsersToRoles( string[] userNames, string[] roleNames); public abstract void RemoveUsersFromRoles( string[] usernames, string[] roleNames); public abstract string[] GetUsersInRole( string roleName); public abstract string[] FindUsersInRole( string roleName, string usernameToMatch); public abstract string[] GetRolesForUser( string userName); public abstract bool IsUserInRole( string username, string roleName); }
Arkitekturen [PrincipalPermissionAttribute( SecurityAction.Demand, Role="Supervisor")] public void MyMethod(string input) {...} Din kod Konfiguration Val av lagring och administration <add name="AuthorizationManagerRoleProvider" type="AuthorizationManagerRoleProvider, Service" description="Role Provider to Authorization Manager" store="msxml://C:\apps\RoleProvider\AuthorizationStore.xml" applicationName="RoleProvider"/>
Resurser Webbsidor Bloggar Böcker och tidskrifter Programming ”Indigo” MSDN Magazine