Einfaches WCF-Beispiel ohne komplizierte Config
Unter anderem durch die Aktivität im myCSharp.de-Forum ist mir aufgefallen, dass viele Entwickler doch Probleme mit der Konfiguration von WCF-Diensten haben. Zugegeben; ich bin auch kein großer Fan des .NET-Konfigurationsframeworks. Es vereinfacht manches, aber es verkompliziert auch vieles, da unnötige Werte Verwirrung stiften.
Das finde ich wirklich schade. Denn dabei ist ein WCF-Service fundamental in wenigen Zeilen geschrieben. Ihr braucht dafür nur 3 Projekte:
<img src="/contents/2016/WCFCalcExample_Projektuebersicht.png"
Das Betreiben von WCF in Konsolen-Anwendungen nennt man "self-hosted". Entgegen dem zentralen Betreiben auf Webservern wie dem IIS, kann der WCF hier in einer Anwendung gehalten werden, um zum Beispiel eine Process-To-Process-Kommunikation zu ermöglichen; im Gegensatz zur klassischen IPC ist es hiermit jedoch einfacher auch Maschinen-übergreifend zu kommunizieren.
Beispielhaft habe ich hier ein WCF-Service (CalcService) erstellt, der die grundlegenste, bidirektionale Kommunikation darstellt: eine einfache Addition auf Server-Seite. Der Client liefert dafür die beiden Zahlen-Werte und erhält die Summe als Antwort.
Code Client:
// Client Source
class Program
{
public const String Host = "net.tcp://localhost";
public const Int32 Port = 31227;
public const String ServiceName = "MathService";
static void Main( string[ ] args )
{
// Address
string svcAddress = Host + ":" + Port + "/" + ServiceName;
// Binding
NetTcpBinding tcpb = new NetTcpBinding( SecurityMode.Message );
ChannelFactory<ICalcService> chFactory = new ChannelFactory<ICalcService>( tcpb );
// Endpoint
EndpointAddress epAddress = new EndpointAddress( svcAddress );
// Create Channel
ICalcService calcService = chFactory.CreateChannel( epAddress );
Console.WriteLine( "Connected to service '" + svcAddress + "'." );
var result = calcService.Add( 4, 5 );
Console.WriteLine( "The result of 4+5 is '" + result + "'." );
Console.WriteLine( "Press key to quit." );
Console.ReadKey( );
chFactory.Close( );
}
}
Code Server:
class Program
{
public const String Host = "net.tcp://localhost";
public const Int32 Port = 31227;
public const String ServiceName = "MathService";
static void Main( string[ ] args )
{
string svcAddress = Host + ":" + Port + "/" + ServiceName;
Uri svcUri = new Uri( svcAddress );
using ( ServiceHost sh = new ServiceHost( typeof( CalcService ), svcUri ) )
{
// Binding
NetTcpBinding tcpBinding = new NetTcpBinding( SecurityMode.Message );
// Behavior
ServiceMetadataBehavior behavior = new ServiceMetadataBehavior( );
sh.Description.Behaviors.Add( behavior );
sh.AddServiceEndpoint( typeof( IMetadataExchange ), MetadataExchangeBindings.CreateMexTcpBinding( ), "mex" );
//Endpoint
sh.AddServiceEndpoint( typeof( ICalcService ), tcpBinding, svcAddress );
// Open
sh.Open( );
Console.WriteLine( "Service started '" + svcAddress + "' ...Press key to quit." );
Console.ReadKey( );
Console.WriteLine( "Quit. Press key to close." );
Console.ReadKey( );
// Close
sh.Close( );
}
}
}
Client und Server müssen beide die Schnittstelle des Services kennen. Diese Logik ist in einem dritten Projekt ausgelagert.
Code Service
[ServiceContract]
public interface ICalcService
{
[OperationContract]
int Add( Int32 n1, Int32 n2 );
}
public class CalcService : ICalcService
{
public int Add( Int32 n1, Int32 n2 )
{
return n1 + n2;
}
}
Download / CodePlex
Der vollständige Quellcode ist unter CodePlex als WCFCalcExample verfügbar.