Bonjour,
désolé de poster un nouveau message à propos des custom attributes. Les exemples que j'ai pu trouvés sur internet ne m'ont pas permis de comprendre ce qui ne va pas dans mon code
Dans une dll:
[assembly:AssemblyDependencies( "ee","1.0.0.0","aa", "1.0.0.0")]
le custom atttribute est défini ainsi::
[AttributeUsage(AttributeTargets.Assembly)]
public class AssemblyDependencies : Attribute
{
public Hashtable Dependencies;
public AssemblyDependencies(params string[] dependencies)
{
Dependencies = new Hashtable();
if (dependencies.Length % 2 == 0)
{
for(int count = 0; count < dependencies.Length; count += 2)
{
try
{
this.Dependencies.Add(dependencies[count], new Version(dependencies[count+1]));
}
catch(Exception e)
{
Console.WriteLine("Error");
}
}
}
}
}
Dans un autre programme, je charge la dll:
Assembly asm = Assembly.LoadFrom(this.fullName);
Attribute[] attributes;
try
{
attributes = Attribute.GetCustomAttributes(asm);
}
catch(Exception e)
{
Console.WriteLine("Error");
}
foreach(Attribute attribute in attributes)
{
AssemblyDependencies dependencies = attribute as AssemblyDependencies;
if (dependencies != null)
{
try
{
Console.WriteLine("{0}", dependencies.Dependencies);
}
catch(Exception e)
{
Console.WriteLine("Error");
}
}
else
Console.WriteLine("{0} is null", attribute);
}
}
Prblème: j'ai "AssemblyDependencies is null"!
Pourtant, quand je fais exactement la même chose pour System.Reflection.AssemblyTitleAttribute, cela marche correctement
Le chemin de la dll est correct, et les dependences sont correctement ajoutées dans AssemblyDependencies
Qu'est-ce qui ne va pas dans ce bout de code?
Merci
# monodis
Posté par jusob . Évalué à 1.
.assembly extern mscorlib
{
.ver 1:0:5000:0
}
.assembly 'Plugin'
{
.custom instance void class [mscorlib]System.Reflection.AssemblyTitleAttribute::.ctor(string) = (
01 00 18 4A 75 6C 69 65 6E 53 6F 62 72 69 65 72 // ...JulienSobrier
46 69 72 73 74 50 6C 75 67 69 6E 00 00 ) // FirstPlugin..
.custom instance void class AssemblyEventsTrigger::.ctor(string[]) = (
01 00 02 00 00 00 07 6F 6E 53 74 61 72 74 06 6F // .......onStart.o
6E 53 74 6F 70 00 00 ) // nStop..
.custom instance void class AssemblyDependencies::.ctor(string[]) = (
01 00 04 00 00 00 02 65 65 07 31 2E 30 2E 30 2E // .......ee.1.0.0.
30 02 61 61 07 31 2E 30 2E 30 2E 30 00 00 ) // 0.aa.1.0.0.0..
.hash algorithm 0x00008004
.ver 0:1:1:1
}
[...]
# chezmoicamarche.org
Posté par TImaniac (site web personnel) . Évalué à 3.
Premièrement c'est normale le is null, tu fais ton test dans une boucle foreach, et tu peux très bien trouvé tout pleins d'autres attributes uqi ne sont pas les tiens.
En tout cas chez moi j'ai essayé ton attribute dans une dll, et j'ai testé avec ca :
Assembly asm = Assembly.LoadFrom("plugin.dll");
Attribute[] attributes = Attribute.GetCustomAttributes(asm);
foreach(Attribute attribute in attributes)
{
if (attribute is AssemblyDependencies)
{
Console.WriteLine("trouvé !");
AssemblyDependencies ds = (AssemblyDependencies)attribute;
foreach(string s in ds.Dependencies.Keys) Console.WriteLine(s+" : "+ds.Dependencies[s]);
}
}
et ma fois ca marche nickel, j'obtiens ca en résultat :
trouvé !
aa : 1.0.0.0
ee : 1.0.0.0
Sinon plutôt que de faire un attribute avec un nombre variable d'argument, tu peux aussi en mettre que 2, nom+version, et proposer à l'utilisateur de mettre plusieurs fois l'attribut s'il veut multiplié les dependances.
Ah oui aussi je sais pas trop ce que tu veux faire, mais la gestion des dépendances d'habitudes c'est un obulot réservé au CLR, et tu n'as absolument rien à faire pour les gérer mais bon :)
[^] # Re: chezmoicamarche.org
Posté par jusob . Évalué à 1.
Je sais, le probleme est que AssemblyDependencies est egalement null.
Merci beaucoup d'avoir teste. mais chez moi, ca ne marche toujours pas avec le code que tu as donne!
Faut-il compiler le plugin avec certaines otpions? J'ai juste fait "mcs -target:library Plugin.cs ../PluginInterface.cs ../Session.cs"Faut-il utiliser
C'est note
CLR?
[^] # Re: chezmoicamarche.org
Posté par jusob . Évalué à 1.
[^] # Re: chezmoicamarche.org
Posté par TImaniac (site web personnel) . Évalué à 2.
Visiblement tu compiles ton plugin avec le source de l'attribute, puis tu recompiles le programme qui cherche les plugins avec ce même source... je me trompes ?
Donc du coup chacun a sa version de la définition, et malgrès le partage de source, le CLR (Common Langage Runtime, autrement dit l'environnement d'exécution, plus comunément appelé machine virtuelle, qui se lance avec la commande mono) voit 2 versions différentes (ils ont chacuns un numéro de version, etc.)
Ce qu'il faut faire dans ton cas précis :
compiler dans une dll tout ce qui doit être "partagé", autrement dit ce qui doit être connu des plugins et du gestionnaire de plugin, cad en gros les def d'attributes, les interfaces, les classes manipulables par les plugins, etc.
mcs -
ensuite tu compiles un plugin comme ceci :
mcs -target:library monPlugin.cs -r:MonAppliQuiContientLesDefs.dll
les def d'attributs sont dans MonAppliQuiContientLesDefs.dll.
Tu peux également y mettres ton gestionnaire de plugin, celui qui les charges, mais tu peux aussi mettre ton gestionnaire à part. Il se compilera alors de la même façon :
mcs -target:library monGestionnaire.cs -r:MonAppliQuiContientLesDefs.dll
ou dans une application :
mcs monAppli.cs -r:MonAppliQuiContientLesDefs.dll
en espérant que ca marche mieux maintenant :-)
Si ca marche toujours pas tu peux me mailer si tu veux.
[^] # Re: chezmoicamarche.org
Posté par jusob . Évalué à 1.
C'est exactement ca, apparemment. Merci beaucoup
Par contre, je ne comprends pas tous les details du probleme. Cela siginifie que la definition de AssemblyDependencies n'est pas la meme pour les differents programmes car au moment ou se fait la compilation (ou l'execution?), une version differente est donnee a AssemblyDependencies par chaque (instance de ?) programme? Bug ou feature? :-)
J'ai fait tout ce que tu as indique, et ca marche bien, a 2 details pres:
* l'exe et Plugin.dll doivent etre compiles avec le source code de PluginInterface. Mettre ce code dans une dll commune (avec les defs) ne fonctionne pas: "Cannot find type PluginInterface" a la compilation. Du coup, je retombe sur ce probleme quand dans l'exe j'essaye de voir si Plugin.dll implemente l'interface PluginInterface. Commen regler ca?
* MonAppliQuiContientLesDefs.dll doit etre dans le meme repertoire que l'exe au lancement. J'imagine que c'est uniquement un probleme de library path, je regarderai ca plus tard.
Merci beaucoup pour l'aide.
[^] # Re: chezmoicamarche.org
Posté par TImaniac (site web personnel) . Évalué à 2.
(celà ne veut pas du tout dire que tu es obligé de signer numériquement tes assembies avec sn.exe)
Mettre ce code dans une dll commune (avec les defs) ne fonctionne pas: "Cannot find type PluginInterface" a la compilation.
T'as du te planter quelque part.
En général chez moi tout ce qui est partagé par les plugins (donc les defs et sans doute ton PluginInterface) sont dans une dll séparée, dans un namespace, comme ceci :
namespace MonAppli.Core.PluginSystem {
public interface...
public attributes...
}
(le plus souvent c'est même dans le coeur de mon appli, dans MonAppli.Core.dll)
et pour développer un plugin, un développeur odit juste référencer ta dll avec mcs :
mcs -t:library -r:MonAppli.Core.dll
bien sûr dans son code il doit écrire quelquechose comme :
using MonAppli.Core.PluginSystem;
pour "importer" les defs.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.