.NET 3.0 en liten översikt - del 1
Förord
Microsoft har nyligen släppt version 3.0 av .NET frameworket. Vad innehåller det för nytt och användbart då? Vi ska granska en del av nyheterna i en liten artikelserie.Innehåll
»»
»
»
»
»
»
»
»
»
Relaterade artiklar
» .NET 3.0 en liten översikt - del 2» .NET 3.0 en liten översikt - del 3
» .NET 3.0 en liten översikt - del 4 (WPF)
» .NET 3.0 en liten översikt - del 5 (WPF)
» .NET 3.0 en liten översikt - del 6 (WPF) - sista delen
Först ska vi kanske påpeka att version 3.0 innehåller faktiskt inte så mycket nytt som man kanske tror av versionsnumret, framför allt så är t.ex. C# 3.0 och .NET 3.0 INTE samma sak. Förenklat kan man säga att 3.0 Frameworket är en påbyggnad till 2.0 med främst tre nya teknologier.
Vi kommer i huvudsak att titta på dom två första.
Extensionerna för Visual Studio är inte helt nödvändiga, men gör livet enklare. Det kan dock påpekas att dessa ännu inte är den slutliga produkten.
Jag har valt att göra artikelserien som en fallstudie, och fallet vi ska se på är en (simpel) chatt klient och server.
Vad är då WCF och vad är det bra för? I dagens läge med SOA och webbservices och överlag distribuerade applikationer, så finns det många olika tekniker man kan använda sej av, med dess egna svagheter och starkheter. Vanligen har man valt en teknik först och sedan efter ett tag kommit fram till om den är bra eller dålig.
Med WCF har Microsoft försökt samla alla dessa tekniker, COM+, webservices etc. under ett gemensamt programmeringsgränssnitt (API) vilket gör att du inte låser dej vid en specifik teknologi (förutom WCF då) och du har möjlighet att konfigurera de olika delarna efteråt.
WCF har tre delar, eller ABC som dom också kan kallas.
Adressen talar om var servicen finns
Bindningen handlar om transport, textkodning, transaktionsstöd osv.
Kontraktet är dina affärsregler för hur servicen fungerar.
För att definiera kontraktet skriver man vanligtvis ett vanligt .NET interface och hänger på ett antal attribut som anger metadata om kontraktet. Vi skall just se hur det ser ut i praktiken.
Klienter skall kunna ansluta och koppla från, skicka meddelanden och få meddelanden.
Vårt huvudsakliga gränssnitt kan då se ut så här.
Det interface som servern använder sej av för att kalla tilbaka till klienterna kan se ut t.ex. som följande.
Message i callback kontraktet är här en egen typ, och för att den skall kunna serialiseras på rätt sätt behöver vi märka även den med några attribut.
Undantaget vi har angett att kan kastas behöver vi också definiera. Nånting i stil med följande blir bra:
Eftersom artikeln redan nu börjar vara rätt lång, så avslutar vi första delen av artikelserien här. Nu har vi ändå definierat våra interface. I del två i serien kommer vi att se på hur vi bygger server delen av servicen.
Den fullständiga källkoden till fallstudien kommer att laddas upp till programarkivet när artikelserien avslutas.
Frågor, kommentarer mottas tacksamt!
- WCF – Windows Communication Foundation (Indigo)
- WPF – Windows Presentation Foundation (Avalon)
- WF – Windows Workflow Foundation
Vi kommer i huvudsak att titta på dom två första.
Vad behöver du som utvecklare?
- .NET 3.0 Runtime
- SDK
- Visual Studio 2005 extensions for .NET Framework 3.0
- Visual Studio 2005 extensions for .NET Framework 3.0 (Windows Workflow Foundation)
- SDK
Fallstudien
Jag har valt att göra artikelserien som en fallstudie, och fallet vi ska se på är en (simpel) chatt klient och server.
WCF – WTF?
Vad är då WCF och vad är det bra för? I dagens läge med SOA och webbservices och överlag distribuerade applikationer, så finns det många olika tekniker man kan använda sej av, med dess egna svagheter och starkheter. Vanligen har man valt en teknik först och sedan efter ett tag kommit fram till om den är bra eller dålig.Med WCF har Microsoft försökt samla alla dessa tekniker, COM+, webservices etc. under ett gemensamt programmeringsgränssnitt (API) vilket gör att du inte låser dej vid en specifik teknologi (förutom WCF då) och du har möjlighet att konfigurera de olika delarna efteråt.
WCF har tre delar, eller ABC som dom också kan kallas.
- Adress (address),
- bindning (binding)
- kontrakt (contract).
Adressen talar om var servicen finns
Bindningen handlar om transport, textkodning, transaktionsstöd osv.
Kontraktet är dina affärsregler för hur servicen fungerar.
Definiera kontrakt
För att definiera kontraktet skriver man vanligtvis ett vanligt .NET interface och hänger på ett antal attribut som anger metadata om kontraktet. Vi skall just se hur det ser ut i praktiken.
Vad behövs för vår service då?
Klienter skall kunna ansluta och koppla från, skicka meddelanden och få meddelanden.
Chat interface
Vårt huvudsakliga gränssnitt kan då se ut så här.
using System.ServiceModel;
namespace LemonDesign.Chat.Contract {
///
/// Chat interface. In order to use communication in both directions, we have to indicate a callback
/// interface. We also indicate some nice namespace (otherwise we would get http://tempuri.org)
///
[ServiceContract(SessionMode=SessionMode.Required,
CallbackContract=typeof(IChatEvents),
Namespace="urn:LemonDesign:Chat")]
public interface IChat {
///
/// Client calls connect to tell server that it is there and what the name of the client is.
/// In the attributes we can specify that this operation is a one-way operation, and that this is
/// the first operation to be called.
///
/// the name of the client
[OperationContract(IsInitiating=true, IsTerminating=false, IsOneWay=true)]
void Connect(string username);
///
/// Client calls disconnect to indicate that it is disconnecting. The attribute parameters
/// indicate that this is the last operation to be called.
///
[OperationContract(IsInitiating=false, IsTerminating=true, IsOneWay=true)]
void Disconnect();
///
/// This is the method that the client uses to say stuff to the client.
/// It is neither the first nor the last operation.
///
/// the message
/// This exception can be thrown
/// if the server considers the message to be too obscene.
[OperationContract(IsInitiating=false, IsTerminating=false)]
[FaultContract(typeof(ObscenityException))]
void Say(string message);
}
}
Callback interface
Det interface som servern använder sej av för att kalla tilbaka till klienterna kan se ut t.ex. som följande.
using System.ServiceModel;
namespace LemonDesign.Chat.Contract {
///
/// Callback interface for Chat service
///
[ServiceContract(Namespace="urn:LemonDesign:Chat")]
public interface IChatEvents {
///
/// Server calls client to notify about a new message
///
/// the new message
[OperationContract(IsOneWay=true)]
void MessageReceived(Message message);
///
/// Server can notify that it is shutting down.
///
[OperationContract(IsOneWay=true)]
void ServerGoingDown();
}
}
Custom data
Message i callback kontraktet är här en egen typ, och för att den skall kunna serialiseras på rätt sätt behöver vi märka även den med några attribut.
using System;
using System.Runtime.Serialization;
namespace LemonDesign.Chat.Contract {
///
/// A chat message
///
[DataContract(Namespace="urn:LemonDesign:Chat")]
public class Message {
private string m_content;
private DateTime m_timestamp;
private string m_sender;
///
/// Create a new message
///
/// the sender of the message
/// the content
public Message(string sender, string content) {
m_sender = sender;
m_content = content;
m_timestamp = DateTime.UtcNow;
}
///
/// The sender of the message.
///
[DataMember]
public string Sender {
get { return m_sender; }
set { m_sender = value; }
}
///
/// The content of the message.
///
[DataMember]
public string Content {
get { return m_content; }
set { m_content = value; }
}
///
/// The timestamp of the message.
///
[DataMember]
public DateTime Timestamp {
get { return m_timestamp; }
set { m_timestamp = value; }
}
}
}
Felkontrakt
Undantaget vi har angett att kan kastas behöver vi också definiera. Nånting i stil med följande blir bra:
using System;
using System.Runtime.Serialization;
namespace LemonDesign.Chat.Contract {
///
/// Obscenity exception
///
[DataContract(Namespace="urn:LemonDesign:Chat")]
public class ObscenityException : Exception {
public ObscenityException() { }
public ObscenityException(string message) : base(message) { }
public ObscenityException(string message, Exception inner) : base(message, inner) { }
}
}
Sammanfattning
Eftersom artikeln redan nu börjar vara rätt lång, så avslutar vi första delen av artikelserien här. Nu har vi ändå definierat våra interface. I del två i serien kommer vi att se på hur vi bygger server delen av servicen.Den fullständiga källkoden till fallstudien kommer att laddas upp till programarkivet när artikelserien avslutas.
Frågor, kommentarer mottas tacksamt!
Pelle Johansson
I tidningen hack denna vecka - http://www.derigomedia.com/hack/arkiv/hack20061213.html