Vendredi 30 Juin 2006
Récupérer le chemin courant de votre application avec VB.NET /s .NETCF
Les espaces de noms nécessaires sont:
• System.Reflection
• System.IO
Par dotnet, Vendredi 30 Juin 2006 à 13:50 GMT+2 dans PDA
Vendredi 30 Juin 2006
Par dotnet, Vendredi 30 Juin 2006 à 13:50 GMT+2 dans PDA
Vendredi 31 Mars 2006
Une petite histoire
Un jour mon boss entre dans mon bureau et me demande si c’est facile de faire communiquer deux applications GRC distantes (Gestion de la Relation Client) développées sous .NET sachant qu’on n’avait pas la main sur l’une d’elles. J’ai répondu qu’il suffit de passer par .NET Remoting (trop lourd) ou utiliser un WebService (inadapté) car on n’avait besoin que d’une méthode (celle qui retourne les infos concernant le nouveau client). Mauvaise réponse !
L’idée :
La première application avais pour rôle de créer de nouveaux clients et d’effectuer un minimum de vérifications (adresse postale, mail, âge, …) et la seconde devait récupérer ces informations pour géocoder les adresses postales afin de les placer sur une carte.
Le principe:
Le principe serait d’avoir un répertoire commun aux deux applications dans lequel l’application 1 pourra déposer la description du nouveau client et l’application 2 devra vérifier à intervalle régulier si un nouveau client a été créé.
L’architecture :
Les deux applications appartenant au même réseau local (et domaine) nous avons créé un répertoire partagé nommé Spy contenant un fichier nommée Customers.xml.
L’application 1 devait créer un client puis le rajouté dans le fichier xml et l’application 2 vérifier à intervalle régulier si le fichier avait été modifié pour le lire.
Cette technique est très utilisée dans les applications EAI pour faire communiquer plusieurs applications hétérogènes.
La solution :
Après un peu de recherche sur le web j’ai vu que je n’avais pas à développer des containers ni de connecteurs comme dans les EAI puisque .NET offre une classe très particulière et peu utilisé qui permet de le faire : FileSystemWatcher.
Pour le faire :
using System;
using System.IO;
namespace ConsoleApplicationTests
{
/// <summary>
/// Description résumée de Class1.
/// </summary>
class
Class1
{
/// <summary>
/// Point d'entrée
principal de l'application.
/// </summary>
[STAThread]
static void
{
// Création de l’objet FileSystemWatcher
FileSystemWatcher
MyWatcher = new FileSystemWatcher();
// Répertoire à surveiller
\\par-madiop\Spy
MyWatcher.Path =
@"\\MaMachine\Spy";
// Ne pas surveiller les répertoires
fils
MyWatcher.IncludeSubdirectories = false;
// Filtre pour les notifications
MyWatcher.NotifyFilter = NotifyFilters.LastAccess |
NotifyFilters.LastWrite
|
NotifyFilters.FileName
|
NotifyFilters.DirectoryName;
// Superviser uniquement le fichier Customers.xml
MyWatcher.Filter
= "Customers.xml";
//En cas de changement de
Customer.xml -> appeler la méthode OnChange
MyWatcher.Changed += new FileSystemEventHandler(OnChanged);
//En cas de création de Customer.xml
-> appeler la méthode OnChange
MyWatcher.Created += new FileSystemEventHandler(OnChanged);
// Permettre le composant de
commencer à superviser nles changements
MyWatcher.EnableRaisingEvents = true;
//Maintenir la console afficher pour voir défiler les
changements
Console.WriteLine("Press \'q\' to
quit.");
while(Console.Read()!='q');
}
public static void OnChanged(object source, FileSystemEventArgs
e)
{
Console.WriteLine("{0}
: Changed", System.DateTime.Now);
}
}
}
Par dotnet, Vendredi 31 Mars 2006 à 15:04 GMT+2 dans Astuces du Mois
Lundi 20 Mars 2006
Dans cet article je vais expliquer en quelques étapes comment faire une application distribué avec la technologie .NET Remoting.
IDE : Visual studio 2003 avec le .NET Framework 1.1
Langage : C#
.NET Remoting est une technologie offerte avec le Framework .NET et permet de faire de la programmation distribuée. La programmation distribuée permet par principe d’exécuter un processus sur plusieurs machines. Le but étant d’exécuter des parties du processus sur des machines qui sont le plus disposées à l’effectuer (gros calculs, traitement métier, …).
Voici notre scenario :
Nous disposons d’une application de gestion de compte bancaire qui est composée de trois applications reparties dans toute la France.

Pour visualiser le schéma vous devez avoir un web browser IE
Il est utile de comprendre l’architecture du .NET remoting.
En gros : vous avez d’un côté un serveur puis de l’autre un ou plusieurs client comme ci-dessous.

Pour visualiser le schéma vous devez avoir un web browser IE
L’échange de données peut se faire via HTTP ou TCP (dans notre cas nous utiliserons le protocole TCP). HTTP est plus adapté pour des communications distantes nécessitants le réseau web et TCP pour des communications en réseaux locaux (format binaire, plus performant). Le format d’échange peut être du Xml ou du binaire.
Important :
Dans notre cas les applications 1 et 2 sont des serveurs et l’application 3 le
client
Il est intéressant de savoir que le client ne manipule jamais les objets hébergé par le serveur mais passe par se qu’on appelle des proxies.
En effet, les proxies sont
les représentants locaux des objets distants. Pour communiquer avec un objet
distant, on instancie un proxy qui sera la représentation locale de cet objet.
On manipule le proxy comme si c’était notre objet distant.
Dans notre cas nous allons avoir deux proxies
(un pour l’application 1 et l’autre pour l’application 2). Un proxy étant un
objet, il est donc représentable par une classe ou une interface.
A ce stade nous avons toutes les entités nécessaires, reste plus qu’à les meubler.
Projet Lib_App2
Son rôle est de calculer un agio à partir d’un montant représentant le découvert bancaire
Renommer class1 en LibApp2 ainsi que le fichier (LibApp2.cs)
La classe LibApp2 doit
forcément dériver de MarshalByRefObject
Ajouter au projet une méthode nommée float getAgio(float fDec)
Le projet Lib_App1
Son rôle est de récupérer le montant du découvert de la base de données puis d’interroger l’application 2 pour avoir le montant de l’agio.
Renommer class1 en LibApp1 ainsi que le fichier (LibApp1.cs)
La classe LibApp1 doit
forcément dériver de MarshalByRefObject
Ajouter une méthode nommée void getAgioAndDec(long lIDClient, ref float fDec, ref float fAgio)
Ajouter une interface nommée IApp2 (proxy de Lib_App2) –fichier IApp2.cs-
Le projet Svr_App2
Renommer Class2 en App2 ainsi que le fichier (App2.cs au lieu de Class1.cs)
Ajouter une référence du projet Lib_App2
Le projet Svr_App1
Renommer Class1 en App1 ainsi que le fichier (App1.cs au lieu de Class1.cs)
Ajouter une référence du projet Lib_App1
Le projet clt_App3
Ajouter un bouton, une textbox, et un label
Dans le textbox vous saisirez l’ID du client et l’appui sur le bouton invoquera les méthodes distantes puis le résultat sera affiché dans le label.
Ajouter une interface nommée IApp1 (proxy de Lib_App1) –fichier IApp1.cs-
Au niveau des deux
serveurs
Ajouter
les références suivantes (fichier App1.cs et App2.cs) :
using
System;
using System.Collections;
using System.Runtime.Remoting;
using MyTcpChannel = System.Runtime.Remoting.Channels.Tcp.TcpChannel;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels;
Attention: Vous devez ajouter la référence
de l’assembly System.Runtime.Remoting
à vos projets (Click droit sur le projet puis ajouter référence)
Pour “servir un objet” on doit:
Et tout ça dans la méthode main
Au niveau du client
(clt_App3)
using
System;
using System.Collections;
using System.Runtime.Remoting;
using MyTcpChannel = System.Runtime.Remoting.Channels.Tcp.TcpChannel;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels;
Attention: Vous devez ajouter la référence
de l’assembly System.Runtime.Remoting
à vos projets (Click droit sur le projet puis ajouter référence)

Pour visualiser le schéma vous devez avoir un web browser IE
Si vous voulez les codes complets envoyez moi un mail à l’@ suivante :bossiel@yahoo.fr
Svr_App1 :App1.cs
using System;
using System.Collections;
using System.Runtime.Remoting;
using MyTcpChannel
= System.Runtime.Remoting.Channels.Tcp.TcpChannel;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels;
namespace
Svr_App1
{
/// <summary>
/// Description résumée de Class1.
/// </summary>
class
App1
{
/// <summary>
/// Point d'entrée
principal de l'application.
/// </summary>
[STAThread]
static void
{
BinaryServerFormatterSinkProvider
serverProv = new BinaryServerFormatterSinkProvider();
serverProv.TypeFilterLevel
= System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;
BinaryClientFormatterSinkProvider
clientProv = new BinaryClientFormatterSinkProvider();
IDictionary
props = new Hashtable();
props["port"] = 1234;//port
//(1): Ouvrir un canal selon le protocole tcp et sur un port 1234
// Enregistrer le canal ouvert précédemment
MyTcpChannel _tcpChannel = new MyTcpChannel(props,clientProv,serverProv);
ChannelServices.RegisterChannel(_tcpChannel);
//(2): Publier son type avec l’URI et le mode pour y
accéder
RemotingConfiguration.RegisterWellKnownServiceType(typeof(Lib_App1.LibApp1),"Svr_App1",WellKnownObjectMode.SingleCall);
Console.Write("**********************************************\n");
Console.Write("
MON SERVEUR Svr_App1 \n");
Console.Write("***********************************************\n");
Console.Write("Moi
je suis un serveur d'application conçu pour Lib_App1 distant\nqui sera utilisé par un client autonome (App3) via tcp/http au format binaire ou soap\n");
Console.Write("\n\n");
Console.Write("-Je
viens de me lancer sur tcp:1234\n\n");
Console.Write("-Je
viens de demarrer l'objet distant ok\n\n");
Console.Write("[Entree] pour quitter");
Console.ReadLine();
ChannelServices.UnregisterChannel(_tcpChannel);
}
}
}
Lib_App1 :LibApp1.cs
using System;
using System.Collections;
using System.Runtime.Remoting;
using MyTcpChannel
= System.Runtime.Remoting.Channels.Tcp.TcpChannel;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels;
namespace
Lib_App1
{
/// <summary>
/// Description résumée de Class1.
/// </summary>
public
class LibApp1 :MarshalByRefObject
{
public LibApp1()
{ }
public void getAgioAndDec(long lIDClient, ref float fDec, ref float fAgio)
{
//les calcul sont fictifs: ajouter du code pour acceder à une DB
if(lIDClient
> 0)
{
fDec = -152;//toujours
fAgio = getAgio2(fDec);
}
}
/// <summary>
/// Cette methode
appel l'objet distant Lib_App2 pour avoir le montant de l'agio
/// sachant
à combien s'éleve le découvert.
/// Pour que cette méthode
marche il faut que le serveur Svr_App2 soit démarré
/// </summary>
/// <returns></returns>
private float
getAgio2(float fDec)
{
//(1): Ouverture du canal selon le protocole Tcp
MyTcpChannel _tcpChannel = new MyTcpChannel(1);
//(2): Enregistrement du canal ouvert précédemment
ChannelServices.RegisterChannel(_tcpChannel);
// (3): Récupération d'une référence de l'objet distant
Lib_App2 hebergé par Svr_App2
Lib_App2.LibApp2 pxy_App2 = (Lib_App2.LibApp2)RemotingServices.Connect(typeof(Lib_App2.LibApp2),
"tcp://localhost:5678/Svr_App2");
try
{
return pxy_App2.getAgio(fDec);
}
catch(Exception ex)
{
return -1;
}
finally
{
// (4):
Fermeture et deréférencement du canal
ChannelServices.UnregisterChannel(_tcpChannel);
}
}
}
}
ctl_App3 :IApp1.cs
/*C'est le proxy de l'objet
Lib_App1*/