Soucis sur le Discoverer

0 views
Skip to first unread message

jean-loup kahloun

unread,
Jan 11, 2011, 1:23:50 PM1/11/11
to civikey-dev
Quand un plugin fait explicitement (ou non) reference à un service
dont l'assembly n'est pas découverte,
l'assembly toute entiere n'est pas découverte : Probleme de reference.
Dans ce cas , tout va bien.

Si on fait reference Explicitement (avec l'attribut [Service]), à un
service qui n'implemente pas ICKService : on obtient une Null Ref, en
effet, un ServiceInfo est crée
mais ne contient qu'un assemblyQualifiedName, et rien d'autre,
resultant en une belle Null Ref Exception lors d'une SECONDE
decouverte. Et oui, au moment du merge entre les deux plugins
découverts
on fait appel à la proprieté Service du PluginInfo venant du Runner,
or celle-ci est à null.

Maintenant, passons du côté des IService<T>.
Si on prend un service nommé IYoupiService, IYoupiService implementant
cette fois ICKService.
un ServiceInfo representant IYoupiService est crée lors du passage sur
son assembly, fine.
Mais si dans un plugin on fait reference à IService<IYoupiService>, on
crée un nouveau ServiceInfo, representant IService<IYoupiService>,
n'ayant qu'un assemblyQualifiedName.
Car on ne fait pas le lien entre IService<IYoupiService> et
IYoupiService.

Si je comprends bien le probleme :
1) Un simple ajout d'un test if ( != null) aux différentes étapes du
merge.
2) Il faut ajouter un test
typeof(ICKService).AssignableFrom(TypeDeLaProprieteReference) avant de
créer un ServiceReferenceInfo (et du coup, un ServiceInfo).
3) Il faut bien faire le lien entre IService<IT> et IT.

Olivier Spinelli

unread,
Jan 22, 2011, 4:58:51 AM1/22/11
to civik...@googlegroups.com
Le discoverer a bien morflé :-).

Il n'y a pas que lui, mais en l'occurrence, un petit point sur le
refactoring du Discoverer:
- IDynamicService est le nouveau nom de ICKService.
- L'architecture du noyau repose en grande partie sur le pattern du
Service Locator via le IServiceProvider (de System.dll et qui a le bon goût
d'accepter l'optionalité des services) et sur un ISimpleServiceContainer et
une implémentation par défaut dans CK.Core.
- Le Discoverer recense maintenant les services qui ne sont pas des
IDynamicService (toute propriété publique de type interface).
- Le fait qu'un plugin référence IService<IYoupi> ou IYoupi, n'est
pas mémorisé par le discoverer car GetService gère:
- Tous les services (que ceux-ci soient implémentés par des
plugins ou injectés de l'extérieur) sont accessibles via
IServiceProvider.GetService, et pour un service dynamique, GetService gère
aussi bien IService<IYoupi> que IYoupi.
- Lorsque IService<IYoupi> est utilisée, la propriété est
injectée même si IYoupi n'est pas disponible.
- Lorsque IYoupi est utilisée, la propriété injectée est
nulle si IYoupi n'est pas disponible.

C'est un peu court mais c'est l'essentiel.

Par ailleurs, nous finalisons la "vitrine" de Civikey, à savoir l'assembly
CK.Plugin.Model qui définit ce qui est nécessaire et suffisant pour:

- Définir un service dynamique (IDynamicService).
- Définir un plugin (PluginAttribute, IPlugin).
- Consommer des services (IService<>, DynamicServiceAttribute,
RequiredServiceAttribute).
- Démarrer/arrêter d'autres composants, grâce à :
- Une classe RequirementLayer qui permet de définir des
contraintes relativement à des services ou des plugins.
- Une façade (ISimplePluginRunner) qui permet d'appliquer
ces RequirementLayer.
- Tout cela s'inscrit dans le namespace CK.Plugin.

Dans ce cadre, nous devons finaliser le RequirementLayer avec ses
IPluginRequirementCollection et IServiceRequirementCollection en supprimant
les interfaces, et en considérant les classes concrètes à implémenter comme
des classes supports (qu'il n'y a donc pas de problème conceptuel à définir
dans un Model).

Un petit mot à Jean-Loup (qui est dessus en ce moment) à ce sujet :
- Tout doit passer en class publique, sauf que l'on garde quand même
les 2 interfaces IPluginRequirementCollection et
IServiceRequirementCollection qui encapsulent la complexité. Seul
RequirementLayer sait créer ces deux collections.
- Pour info: l'implémentation actuelle où je vous ait fort emmer...
avec la liste chaînée, on peut l'oublier :-) au profit d'une KeyedCollection
(je pense). Mais, au fond, peu importe car les 2 classes sont internal
(seules les 2 interfaces sont publiques), donc on pourra changer plus tard.


Un dernier point sur l'assembly CK.Plugin.Config.Model, qui permet
d'exploiter la configuration des plugins (namespace CK.Plugin.Config) :
- L'attribut ConfigurationAccessorAttribute permet de demander
l'accès aux données d'un autre plugin.
- L'interface IPluginConfigAccessor donne accès aux configurations
Systèmes/User/Context et à tout autre objet du contexte.
- L'interface IConfigContainer expose l'interface fondamentale de
gestion de configuration (un dictionnaire associatif de triplet
objet-plugin-key -> objet).
- Les interfaces IObjectPluginAssociation, IConfigEntry,
IConfigObjectEntry, IConfigPluginEntry modélisent les triplets de
configuration (dans les différents sens).
- IObjectPluginConfig est l'interface de configuration simple (key
-> object) pour un couple (object-plugin) donné.


Ces quelques lignes aussi pour initier un début de base de substrat de
documentation relativement à tout cela :-).

Voila.


-----Message d'origine-----
De : civik...@googlegroups.com [mailto:civik...@googlegroups.com] De
la part de jean-loup kahloun
Envoyé : mardi 11 janvier 2011 19:24
À : civikey-dev
Objet : [civikey-dev] Soucis sur le Discoverer

Reply all
Reply to author
Forward
0 new messages