Mini-Projet SNCF avec WCF, WPF, Linq

Bonsoir à tous !

Pour illustrer quelques possibilités offertes par WCF et Linq To SQL dans un projet .NET 3.5, j'ai choisis la thématique SNCF.

En ces temps de grève, on peut imaginer (avec un peu d'effort), que le nom des trains change fréquemment. Cette solution contiendra donc une interface WPF, avec laquelle nous pourrons modifier les noms des trains et ... c'est déjà pas mal. Smile

Encore une fois le but du jeu est de tester et de réfléchir sur l'architecture que l'on peut mettre en place.

I Architecture de la solution :

  • Un projet SNCF.DataAccessLayer avec LinqToSQL.
  • Un projet SNCF.BusinessLayer avec les méthodes métiers.
  • Un projet SNCF.Common pour les objets communs aux projets.
  • un projet SNCF.WCFInterfaces qui définit les contrats.
  • Un projet SNCF.WCFServices qui implémente les méthodes grâce à une classe.
  • Un projet SNCF.WCFHost qui démarre le service WCF.
  • et pour finir, le projet SNCF.UI.WPF qui consommera le service.

 

 

 

 

II Aperçu de l'interface WPF :

III DataAccess et LinqToSQL

Pour le projet d'accès aux données, il me suffit d'ajouter un fichier dbml, d'y ajouter ma table et les différentes procédures stockées, et le tour est joué.

C'est très physique le "glisser déplacer". Geeked

 

 

 

 

 

 

 

III Business Layer

La couche métier définit trois méthodes statiques.

1
2
3
4
5
public static SNCF.Common.Train Get(Guid idTrain);

public static List<SNCF.Common.Train> GetAll();

public static bool Update(SNCF.Common.Train t);

IV WCFInterfaces

Le projet WCFInterfaces va permettre de définir les contrats, on y trouve une interface IServices.

On va déclarer les services que l'on veut utiliser et on y ajoute l'assembly ServiceModel qui va nous permettre de définir les contrats.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using System.ServiceModel;
using SNCF.Common;


namespace SNCF.WCFInterfaces
{
[ServiceContract(Namespace = "http://localhost/WCF/TrainServices")]
public interface IServices
{
[OperationContract]
Train Get(Guid idTrain);


[OperationContract]
List<Train> GetAll();


[OperationContract]
bool Update(Train t);
}
}

VI WCFServices

Après avoir défini les contrats, on va créer une classe qui va implémenter l'interface, j'ai choisi "TrainServices.cs".

Cette classe associe, les méthodes déclarées dans le contrat à la couche BusinessLayer.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using SNCF.WCFInterfaces;
using SNCF.BusinessLayer;
using SNCF.Common;


namespace SNCF.WCFServices
{
public class TrainServices : IServices
{
public Train Get(Guid idTrain)
{
return TrainDAO.Get(idTrain);
}

public List<Train> GetAll()
{
return TrainDAO.GetAll();
}

public bool Update(Train t)
{
return TrainDAO.Update(t);
}
}
}

VII WCFHost

Une fois l'ensemble (DataAccessLayer, BusinessLayer, WCFServices et WCFInterfaces) terminé, nous pouvons démarrer le service WCF.

C'est l'objectif de cette application console.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
using System.ServiceModel;
using SNCF.WCFServices;
using SNCF.WCFInterfaces;


namespace SNCF.WCFHost
{
class Program
{
static void Main(string[] args)
{
ServiceHost host =
new ServiceHost(typeof(TrainServices));

host.AddServiceEndpoint(typeof(IServices),
new BasicHttpBinding(),
"http://localhost/WCF/TrainServices");

host.Open();

Console.WriteLine("Service Disponible");
Console.ReadLine();

host.Close();
}
}
}

VIII WPF UserInterface

L'interface WPF peut à présent se connecter au service.

1
2
3
ChannelFactory<IServices> myFactory;
IServices myService;
public MainWindow(){
   InitializeComponent();               
   myFactory = new ChannelFactory<IServices>(new BasicHttpBinding(),
               http://localhost/WCF/TrainServices);
   myService = myFactory.CreateChannel();            
   // ComboBox DataSource
   cboTrain.ItemsSource = myService.GetAll();
}

Conclusion :

Cette solution est très intéressante pour exposer très facilement toute la structure métier de son application sans se préoccuper de la nature, et de la localisation de l'interface utlisateur qui l'interroge. Si vous avez des remarques sur l'architecture, n'hésitez pas à intervenir, je suis friand de vos idées. Geeked

L'intégralité de la solution est disponible à cette adresse. (La solution est réalisée avec Visual Studio 2008 béta 2).

PS : Cet article peut être amené à évoluer suivant vos remarques.

Publié dimanche 28 octobre 2007 21:07 par davidrei
Classé sous , ,
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :

Commentaires

# re: Linq To SQL, WCF, WPF : Mini-Projet SNCF @ lundi 29 octobre 2007 10:19

Prendre le RER C comme exemple, c'est cherché la gestion de l'exception non gérée ;)

Erebuss

# re: Linq To SQL, WCF, WPF : Mini-Projet SNCF @ mercredi 21 novembre 2007 23:50

Belle exemple d'architecture.

Par contre je trouve un peu fastidieux (voir très lourd) le fait d'être obligé de refinir un contrat de données pour chaque classe linq !

N'y a t-il pas une option dans sqlMetal pour ajouter les attributs [DataContract] devant chaque table et [DataMember] devant chaque champ de la table ?

Christian Gincheleau

# re: [Linq To SQL][WCF][WPF] Mini-Projet SNCF @ vendredi 28 décembre 2007 01:37

Félicitation pour cet article. A quand la suite ?

flanby

# re: [Linq To SQL][WCF][WPF] Mini-Projet SNCF @ mercredi 9 janvier 2008 14:41

Et si la classe Train avait une propriété du type Collection d'horaires ?

Tu fais comment pour la passer au travers de WCF ?

sebmafate

# re: [Linq To SQL][WCF][WPF] Mini-Projet SNCF @ jeudi 28 février 2008 14:38

Si la classe Horaire est sérializable, ça devrait se faire tout seul, à partir du moment on ma classe Train contient une collection d'horaires.

davidrei

# re: Mini-Projet SNCF avec WCF, WPF, Linq @ lundi 7 juillet 2008 17:44

Je trouve le projet trés interressant et l'architecture bien découpée.

Mais la puissance de Link n'est pas du tout exploitée dans ce projet, je dirais même qu'ici Link ne sert à rien puisque pour faire les opérations ADD/UPDATE/INSERT on utilise encore des procédures stockées sur des objets.

Alors que la solution est simple pour le GetAllTrain dans la class  TrainDAO par exemple, le code serait plutôt :

public static List

<SNCF.Common.Train> GetAll()

{

 if (Context.Current.SNCFDataContext != null)

 {

    List<SNCF.Common.Train> listTrain = new List<SNCF.Common.Train>();

    SNCFDataContext sncfContext = new SNCFDataContext();

    foreach (var t in  from e in sncfContext.GetTable<SNCF.DataAccessLayer.Train>() select e)

    {

          listTrain.Add(new SNCF.Common.Train(t.Name, t.TrainPK, t.UrlPicture));

    }

  return listTrain;

 }

    else throw new DatabaseOfflineException();

}

Au lieu de :

public static List<SNCF.Common.Train> GetAll()

{

  if (Context.Current.SNCFDataContext != null)

  {

        List<SNCF.Common.Train> listTrain = new List<SNCF.Common.Train>();

foreach (SNCF.DataAccessLayer.Train t in Context.Current.SNCFDataContext.GetAllTrains())

       {

           listTrain.Add(new SNCF.Common.Train(t.Name, t.TrainPK, t.UrlPicture));

       }

       return listTrain;

    }

    else throw new DatabaseOfflineException();

}

et là dans ce cas on peut plus facilement faire des jointuers entre objet. Pour le rest je n'ai rien à dire je pense que ce code pourra en interresser plus d'un.

thierry behin


Les 10 derniers blogs postés

- [WPF] XPSReader v0.2 par Blog Technique d'Audrey PETIT le il y a 1 heure et 40 minutes

- Entity Framework : providers Oracle, MySQL et PostgreSQL par Matthieu MEZIL le il y a 8 heures et 15 minutes

- [WPF] Nouvel article sur c2i.fr par Richard Clark le 09-06-2008, 17:33

- F# nouvelle CTP 1.9.6.2 (update) par Pierrick's Blog le 09-06-2008, 13:27

- La suite ...Proposition de collaboration rédactionnelle entre les communautés de développeurs et Microsoft France par LucasR le 09-05-2008, 17:45

- [Fun] Votre simulateur de vol avec Microsoft ESP par Julien Chable le 09-05-2008, 12:02

- [Best Practices] Customisation du My Site : Comment le modifier en amont et en aval par The Mit's Blog le 09-05-2008, 10:47

- Patrick Tisseghem s'en est allé ... par The Mit's Blog le 09-05-2008, 10:04

- MS AutoCollage par alex# le 09-05-2008, 09:18

- Un grand SharePointeur nous a quitte : Patrick Tisseghem manquera à la communauté ! par RedoBlog - The .NET Gentleman !!! le 09-05-2008, 08:52