Bonjour,
Il y a deja quelque temps j'ai decouvert ce qu'est reellement la technologie XPCOM de Mozilla Foundation. Suite a ca, j'ai commence a m'interesser vraiment au developpement par composant et j'ai donc egalement lu quelques articles sur la technologie COM de microsoft, et cherche des alternatives.
Je ne suis pas completement satisfait des solutions que j'ai vu jusqu'a present (XPCOM, COM, ICE?)
Je parle principalement de la mise en place du programme et des librairies fournies.
Corrigez moi si je me trompe (c'est pour recevoir des commentaires que je poste en fait)mais voici ce que j'en retiens:
Pour utiliser le "pattern" de developpement par composant, on a besoin de que notre runtime:
1. Permette de charger la DLL specifiee(ou autre "fichier composant").
2. Permette d'instancier une classe depuis la DLL chargee.
3. Permette de decharger la DLL specifiee.
Donc en gros l'interface pour recuperer un composant inconu pour reprendre les termes COM:
Et nos composants
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 public interface IComponentFactory { Object getInstance(Object param,string[] expectedInterfaces); }
On donne meme la possibilite a lutilisateur de passer des parametres a la creation.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 public interface IComponent { string[] getInterfaces(); void CastTo(String s) { if( !getInterfaces().contains(s) ) { throw( new InvalidCastException(); ) } }; }
Puis dans notre runtime on propose les fonctions statiques:
En gros on peut charger les composants en indiquant le fichier a partir duquel charger tout simplement, et on peut liberer la memoire quand approprie soit en passant le path/name du fichier, soit en passant l'objet charge (qui agit comme une factory pour les composants).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 public static String Components.GetClass(Class c); public static IComponent Components.Load(String file); public static void Components.Unload(String file); public static void Components.Unload(IComponent compfactory);
La fonction Load se charge de charger la DLL de facon a ce que les objets crees puissent etre castes correctement ds le langage ds lequel nous sommes.
Imaginons qu'on aie un objet TCPServer dans le fichier "TCPServer.dll" et que notre composant prennent en entree un objet IPEndPoint
On veut pouvoir ecrire un code du genre:
Voila, ca m'a l'air tout a fait possible, et pas besoin de methodes du genre de "AddRef", ou "Release", comme defini par .COM par example.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91 // fichier de declaration pour les interfaces implementees par MyServer // header en C++, cs in csharp par example etc... // La definition est partagee entre les composants clients // et l'implementation namespace SharedNamespace { // Une interface implementee par un composant public interface IOtherInterface { public virtual void OherMethod(); } // Une interface implementee par un composant public interface IMyServer { public virtual void DoSomeStuff(); } } //fichier source pour MyServer namespace ComponentNamespace { using namespace TCPServerns; using namespace MyCOMns; using namespace SharedNamespace; // Implementation du composant derive toujours de IComponent // Aucune classe cliente n'a besoin de connaitre cette classe protected class MyServer : IMyServer, IOtherInterface, IComponent { private ITCPServer server; private IComponentFactory TCPserverFactory; // derive de IComponent public static override string[] getInterfaces() { string[] ifs = new string[2]; ifs[0] = MyCOM.getClassName(IMyServer); ifs[1] = MyCOM.getClassName(IOtherInterface); } // derive de IOtherInterface public override void OherMethod(){return;} // derive de IMyServer public override void DoSomeStuff(){return;} // creation public MyServer(Object o) { this.TCPserverFactory = Components.Load("TCPServer.dll") IPEndPoint ipep = new IPEndPoint(...); string[] expectedif = new string[1]; expectedif[0] = "TCPServer"; this.server= (ITCPServer)TCPServerFactory.getInstance(ipep,expectedif); } } public class MyServerFactory : IComponentFactory { private string[] interfaces = null; public override Object getInstance(Object o, string[] expected) { this.check(expected,MyServer.getInterfaces()); //renvoie une exception si on ne connait pas l'interface demandee... return (new MyServer()); } } } } //fichier source pour le main de l'appli, qui est aussi notre client... namespace Clientns { using namespace MyCOMns; using namespace SharedNamespace; public class MyMain { public void Main() { IComponentFactory MyServerFactory = Components.Load("MyServer.dll") string[] expectedif = new string[1]; expectedif[0] = "IMyServer"; IMyServer server= (IMyServer)MyServerFactory.getInstance(null,expectedif); server.DoSomeStuff(); IOtherInterface OtherShape = (IOtherInterface)server.CastTo(MyCOM.getClassName(IOtherInterface)); return; } } }
On laisse l'utilisateur gerer ses objets comme il a l'habitude de le faire dans son language. On lui permet juste de charger dynamiquement certains modules...
Ca me parrait legerement plus simple que XPCOM ou .COM comme approche, non?
En gros ca necessiterait que nos DLL soient accompagnees d'un fichier descriptif pour savoir ou sont les methodes a aller chercher...
Mais ca a l'air completement faisable de generer ca directement depuis le code(avant ou apres compilation). en regardant de quelles interfaces derive l'objet qui derive de IComponent....
En fait l'idee c de simplifier les choses en se passant de fichier IDL par exemple. Les languages de programmations nous permettent de definir des classes "interfaces", donc il suffirait de generer le fichier IDL a partir du code en lui meme.
Donc en gros 3 simplifications par rapport a XPCOM et COM:
- pas de fichier IDL
- pas de gestion mysterieuse de la memoire. La memoire est geree par l'utilisateur comme il en a l'habitude...
- pas de librairie par defaut: le runtime se contente d'etre capable de charger les composants. Un point c'est tout.
L'idee est que je trouve COM tres intrusif dans la facon d'ecrire le code apres coup...
XPCOM m'a l'air tres proche de ca, neanmoins ils ont besoin d'IDL... Mais c'est peut etre la solution?
Mais j'ai vu pas mal de critiques d'XPCOM sur certains forums... Alors qu'en y repensant j'ai vraiment l'impression que ce sont eux qui tiennent le bon bout a l'heure actuelle?
Quelqu'un aurait-il une solution meilleure que XPCOM a proposer pour la base d'un programme ecrit par composants?
Aussi la distribution d'XPCOM que j'ai touve vient avec XULRunner (pour l'instant c'est ce que j'en ai vu), donc on se prend des milliards de classes dont on n'a pas forcement besoin pour n'importe quelle application lambda.
De la meme facon, ICE a l'air de venir en bloc si on peut se permettre le jeu de mot, donc on compile contre des librairies deja orientee communication, alors que je veux juste compiler contre des librairies qui me permettent de charger des composants (et ensuite charger eventuellement des composants responsables de gerer les communications....)
Merci d'avance pour vos conseils...
Partager