IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Instanciation d'Interface à la volée


Sujet :

C#

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    125
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2007
    Messages : 125
    Points : 109
    Points
    109
    Par défaut Instanciation d'Interface à la volée
    Bonjour,

    Je travaille sur un projet qui doit pouvoir loader des assembly (Workers) à la demande dans un repertoire.
    La solution du serveur contient un projet "WorkerInterface" qui contient seulement la déclaration de mon Interface IWorker.
    J'ai aussi un projet A dont la classe Travailleur implemente IWorker.

    Mon serveur parcours un repertoire à la recherche d'assemblies, récupère leurs types et vérifie qu'ils implémentent l'interface voulue.
    Si c'est le cas, on l'instancie pour le faire travailler.

    Première blague (pour laquelle je cherche une explication):
    Après recherche sur internet, vérifier qu'une assembly implemente une interface, c'est assez simple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Assembly assembly = Assembly.LoadFrom(assemblyPath);
     
    foreach (Type loadedType in assembly.GetTypes())
    {
    	Type interf = loadedType.GetInterface(typeof(IWorker).FullName);
    	if (interf != null)
    		// On en a trouvé un !
    }
    Et oui: 'IsAssignableFrom', 'as', 'is', '==' et 'GetGenericTypeDefinition': toutes ces solutions me renvoient un false quand je vérifie si ça match...


    Seconde blague (pour laquelle je cherche une alternative):

    Quand j'en ai trouvé un, je veux l'instancier:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    object newWorker = Activator.CreateInstance(loadedType);
    IWorker worker = newWorker as IWorker;
    if (worker != null)
    	mWorkers.Add(worker);
    J'avais commencé par la version courte avec les cast direct, mais ça marche pas (pas plus que cette version).
    Mais je ne comprends pas pourquoi !
    Quand je passe dans ce code en pas à pas, l'object retourné par le CreateInstance présente bien mes méthodes de IWorker,
    mais il refuse de le caster à la ligne du dessous.

    je suis pourtant pas fou:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    public class Travailleur : IWorker
    Je me doute que j'ai zappé une étape, mais je vois pas où...

    Toute aide ou remarque (même délirante) est la bienvenue !

    Merci d'avance

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 753
    Points
    39 753
    Par défaut
    Citation Envoyé par ElTchoupi Voir le message
    vérifier qu'une assembly implemente une interface
    Euh... un assembly implémente rien du tout, hein, c'est le type qui implémente une interface... faute d'inattention je suppose

    Citation Envoyé par ElTchoupi Voir le message
    Première blague (pour laquelle je cherche une explication):
    Après recherche sur internet, vérifier qu'une assembly implemente une interface, c'est assez simple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Assembly assembly = Assembly.LoadFrom(assemblyPath);
     
    foreach (Type loadedType in assembly.GetTypes())
    {
    	Type interf = loadedType.GetInterface(typeof(IWorker).FullName);
    	if (interf != null)
    		// On en a trouvé un !
    }
    Et oui: 'IsAssignableFrom', 'as', 'is', '==' et 'GetGenericTypeDefinition': toutes ces solutions me renvoient un false quand je vérifie si ça match...
    - IsAssignableFrom : normalement ça doit marcher, mais tu l'as peut-être utilisé à l'envers, ce n'est pas super intuitif... il faut tester : typeof(IWorker).IsAssignableFrom(loadedType), et non l'inverse.
    - as : je vois pas trop ce que ça vient faire là...
    - is : normal que ça ne marche pas... tu as fait quoi ? loadedType is IWorker ? loadedType est de type Type, et Type n'implémente certainement pas IWorker...
    - == : normal. typeof(IWorker) est le type de l'interface, et loadedType le type d'une classe réelle. Aucune raison que ce soit égal...
    - GetGenericTypeDefinition : rien à voir, c'est pour les types génériques, et ton interface n'est pas générique.

    La solution la plus propre, à mon sens, est celle avec IsAssignableFrom.

    Citation Envoyé par ElTchoupi Voir le message
    Seconde blague (pour laquelle je cherche une alternative):

    Quand j'en ai trouvé un, je veux l'instancier:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    object newWorker = Activator.CreateInstance(loadedType);
    IWorker worker = newWorker as IWorker;
    if (worker != null)
    	mWorkers.Add(worker);
    J'avais commencé par la version courte avec les cast direct, mais ça marche pas (pas plus que cette version).
    "ça marche pas", ça veut dire que worker == null ?

    Tu peux montrer un extrait de code un peu plus complet ?

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    826
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2006
    Messages : 826
    Points : 1 120
    Points
    1 120
    Par défaut
    Salut,

    Pour la blague n° 2 :
    Tu évoques le fait que l'interface et les workitems sont dans des assemblies différentes. es tu sûr que tu charges bien ces deux assembly avant d'utiliser Activator ? Tu peux essayer d'utiliser Activator.CreateInstanceFrom(string,string) qui semble répondre à tes besoins.

    Pur la blague 1 :
    Pourquoi utiliser le .FullName et pas juste typeof(IWorker) ?

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 753
    Points
    39 753
    Par défaut
    Citation Envoyé par cybermaxs Voir le message
    Pour la blague n° 2 :
    Tu évoques le fait que l'interface et les workitems sont dans des assemblies différentes. es tu sûr que tu charges bien ces deux assembly avant d'utiliser Activator ? Tu peux essayer d'utiliser Activator.CreateInstanceFrom(string,string) qui semble répondre à tes besoins.
    S'il a déjà un objet qui représente le type, l'assembly est forcément chargé...

    Citation Envoyé par cybermaxs Voir le message
    Pur la blague 1 :
    Pourquoi utiliser le .FullName et pas juste typeof(IWorker) ?
    Parce que GetInterface prend en paramètre un String, et pas un Type. Oui, c'est bête mais c'est comme ça... Je suppose que c'est pour pouvoir gérer les interfaces non managées. Pour éviter de passer par le nom, on peut utiliser IsAssignableFrom

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    826
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2006
    Messages : 826
    Points : 1 120
    Points
    1 120
    Par défaut
    Citation:
    Envoyé par cybermaxs
    Pour la blague n° 2 :
    Tu évoques le fait que l'interface et les workitems sont dans des assemblies différentes. es tu sûr que tu charges bien ces deux assembly avant d'utiliser Activator ? Tu peux essayer d'utiliser Activator.CreateInstanceFrom(string,string) qui semble répondre à tes besoins.

    S'il a déjà un objet qui représente le type, l'assembly est forcément chargé
    c'est vrai après reflection, que si les types étatient inconnus il aurait eu une exception.

    Citation:
    Envoyé par cybermaxs
    Pur la blague 1 :
    Pourquoi utiliser le .FullName et pas juste typeof(IWorker) ?

    Parce que GetInterface prend en paramètre un String, et pas un Type. Oui, c'est bête mais c'est comme ça... Je suppose que c'est pour pouvoir gérer les interfaces non managées. Pour éviter de passer par le nom, on peut utiliser IsAssignableFrom
    Après lecture de la msdn, c'est vrai. J'ai tout de même pu remarquer que les exemples de la msdn, n'utilisent pas le nom complet (FullName) mais juste le nom de l'interface (http://msdn.microsoft.com/en-us/library/tcctb9t8.aspx)

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 753
    Points
    39 753
    Par défaut
    Citation Envoyé par cybermaxs Voir le message
    J'ai tout de même pu remarquer que les exemples de la msdn, n'utilisent pas le nom complet (FullName) mais juste le nom de l'interface (http://msdn.microsoft.com/en-us/library/tcctb9t8.aspx)
    C'est vrai, normalement on ne précise pas le namespace... donc il faudrait utiliser Name plutôt que FullName

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    125
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2007
    Messages : 125
    Points : 109
    Points
    109
    Par défaut
    Bonjour.. et merci pour vos réponses !

    Pour répondre tout de suite à cybermaxs, j'ai juste pris un "ralongit", mais effectivement, le nom simple marche aussi ! (je l'ai donc changé: à fonctionnalités égales, je préfère le code simple !)

    Tomlev, comme d'hab, merci pour tes réponses explicatives !
    Donc oui, il me renvoie worker == null.
    J'avais bien testé "typeof(IWorker).IsAssignableFrom(loadedType))" (c'est effectivement pas intuitif, mais la traduction litérale correspond...) et il me renvoie false.
    Pas de problème, je peux te poster plus de code, mais quelle partie veux-tu ?
    Je ne voit pas quelle autre part pourrait avoir de l'importance dans ce problème..

    Merci encore

    BTW, je me sers généralement de 'is' pour pas passer par un 'as' et vérifier si ça pète...
    J'avoue que la subtilité du loadedType qui est de type Type et qui donc, n'implemente pas IWorker, hier soir, j'étais complemetement passé à coté...

  8. #8
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 753
    Points
    39 753
    Par défaut
    Citation Envoyé par ElTchoupi Voir le message
    J'avais bien testé "typeof(IWorker).IsAssignableFrom(loadedType))" (c'est effectivement pas intuitif, mais la traduction litérale correspond...) et il me renvoie false.
    Ca c'est bizarre
    Tu es sûr que ton programme et ton assembly chargé dynamiquement utilisent bien la même définition de l'interface ? elle n'est déclarée qu'à un seul endroit ? Vérifie tes références et recompile tout, parce que si ce test renvoie false, c'est que ton type n'implémente vraiment pas IWorker...

    Mets aussi des points d'arrêt pour exécuter en pas à pas et essayer de voir ce qui se passe, ça règle souvent pas mal de problèmes

    Citation Envoyé par ElTchoupi Voir le message
    BTW, je me sers généralement de 'is' pour pas passer par un 'as' et vérifier si ça pète...
    'as' ne "pète" jamais (contrairement à un cast) : ça renvoie null si la conversion n'est pas possible
    Donc plutôt que de faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if (o is Toto)
    {
        Toto t = o as Toto;
    }
    Tu peux faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Toto t = a as Toto;
    if (t != null)
    {
    }
    Par contre 'as' ne fonctionne que sur les types référence, pas les types valeur

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    125
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2007
    Messages : 125
    Points : 109
    Points
    109
    Par défaut
    Thanks for the explanation !

    Je continue mes tests, j'ai cleané puis tout rebuildé, même résultat.
    En passant pas à pas, je vois rien de louche.

    Pour être sur, une fois ce passage "dynamique" passé, si j'ai rien reussi à charger, je le fais "manuellement":

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Travailleur worker = new Travailleur();
    mWorkers.Add(worker);
    en ayant plus haut:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    private List<IWorker> mWorkers;
    Et là, pas de problème, ça passe...
    je me dit que ça prouve que mon travailleur implemente la bonne interface.. mais avec cette histoire, j'ai des doutes sur tout, même les évidences...

    Une question débile: est-ce que le fait d'implémenter explicitement les méthodes de l'interface pourrait changer quelque chose ?

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    125
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2007
    Messages : 125
    Points : 109
    Points
    109
    Par défaut
    Si je résume:

    Je passe en revue mes assemblies et pour chacune, je passe en revue les types qu'elle expose.
    ya un moment, j'en trouve une qui s'appelle 'Travailleur.dll'
    je passe ses types exposés et je trouve la classe 'Travailleur'
    Quand je lui demande si elle a bien 'IWorker' dans ses interfaces, elle me dit "oui oui, c'est bon"
    du coup, je veux instancier un objet à partir du type en question, pas de probleme, mais là, quand j'essaye de le caster en 'IWorker', il me dit qu'il sait pas faire.

    Du coup, je me dit que c'est au niveau du 'Activator.CreateInstance' que ca doit m.rder...

    Le problème, c'est que juste en dessous, j'ai rajouté un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if (typeof(IWorker).IsAssignableFrom(loadedType))
    et .. il rentre jamais dedans...

    Et là, franchement, pour moi, ça veut dire le contraire de ce qu'il m'a dit plus haut....


    AAARRRRGGGGG

  11. #11
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 753
    Points
    39 753
    Par défaut
    Bon, j'ai fait un petit test vite fait :

    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
    static void Main()
    {
    	List<IFoo> foos = new List<IFoo>();
        var types = from t in Assembly.GetExecutingAssembly().GetTypes()
                    where typeof(IFoo).IsAssignableFrom(t)
                    && !t.IsInterface
                    select t;
        foreach (var t in types)
        {
            IFoo foo = Activator.CreateInstance(t) as IFoo;
            if (foo != null)
                foos.Add(foo);
            else
                Console.WriteLine("Oups : {0} n'implémente pas IFoo", t.FullName);
        }
        foreach(var f in foos)
        {
            Console.WriteLine(f);
        }
    }
     
    interface IFoo
    {
    }
     
    class Foo1 : IFoo
    {
    }
     
    class Foo2 : IFoo
    {
    }
     
    class Foo3 : IFoo
    {
    }
     
    class Bar
    {
    }
     
    class Baz
    {
    }
    Et ça donne bien les résultats attendus...

    Citation Envoyé par ElTchoupi Voir le message
    Une question débile: est-ce que le fait d'implémenter explicitement les méthodes de l'interface pourrait changer quelque chose ?
    Non, ça change rien

    Citation Envoyé par ElTchoupi Voir le message
    Le problème, c'est que juste en dessous, j'ai rajouté un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if (typeof(IWorker).IsAssignableFrom(loadedType))
    et .. il rentre jamais dedans...

    Et là, franchement, pour moi, ça veut dire le contraire de ce qu'il m'a dit plus haut....
    Je me demande si y a pas un problème de logique dans ton code... c'est pour ça que je voulais en voir un peu plus. Est-ce que tu pourrais montrer l'ensemble du code qui charge les assemblies et instancie les workers ? Tu en as montré 2 morceaux au début, mais je voudrais voir comment ils s'articulent entre eux

  12. #12
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    125
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2007
    Messages : 125
    Points : 109
    Points
    109
    Par défaut
    Voilà la méthode complète:

    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
     
    protected bool SearchForAssemblies(string aSearchPath)
            {
                // List Dir entries
                string tempPath = Path.GetDirectoryName(System.Reflection.Assembly.GetCallingAssembly().Location);
                string filePath = Path.Combine(tempPath, aSearchPath);
                string[] foundAssemblies = Directory.GetFiles(filePath, "*.dll");
                if ((foundAssemblies == null) || (foundAssemblies.Length == 0))
                {
                    mDAL.Log4System(this, "No assembly was found in the repository directory");
     
                    return false;
                }
     
                // ForEach Entry
                foreach (string assemblyPath in foundAssemblies)
                {
                    mDAL.Log4System(this, "Found assembly '" + assemblyPath + "' in directory");
     
                    Assembly assembly = Assembly.LoadFrom(assemblyPath);
     
                    foreach (Type loadedType in assembly.GetTypes())
                    {
                        Type interf = loadedType.GetInterface(typeof(IRMWorker).Name);
     
                        if (interf != null)
                        {
                            mDAL.Log4System(this,
                                            "Type: '" + loadedType + "' (from '" + assemblyPath + "') is a RM Worker: Instanciating object in memory");
     
                            //IRMWorker newWorker = (IRMWorker)Activator.CreateInstance(loadedType);
                            object newWorker = Activator.CreateInstance(loadedType);
                            IRMWorker worker = newWorker as IRMWorker;
                            if (worker != null)
                                mWorkers.Add(worker);
     
                            if (typeof(IRMWorker).IsAssignableFrom(loadedType))
                            {
                                mDAL.Log4System(this,
                                            "Type: '" + loadedType + "' (from '" + assemblyPath + "') is assignable !");
                            }
     
                        }
                        else
                            mDAL.Log4System(this, "Type: '" + loadedType + "' (from '" + assemblyPath + "') isn't a RM Worker: skipping");
                    }
                }
     
     
                if (mWorkers.Count.Equals(0))
                {
                    mDAL.Log4System(this, "Couldn't Load any assembly, doing the same 'manually'");
     
                    UserManager worker = new UserManager();
                    mWorkers.Add(worker);
     
                }
     
     
                DumpLoadedWorkersInDB();
     
     
                mDAL.Log4System(this, "Loaded " + mWorkers.Count + " workers for Factory");
     
                return true;
            }
    Pour l'instant (dev en cours), la path passé en param est le chemin (relatif) d'output du projet 'UserManager' (dans la même solution) et qui contient une seule classe:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    public class UserManager : RM.Service.IRMWorker
        { ... }
    Si tu as besoin du code complet de cette classe, hesites pas
    (mais bon, ca compile donc la ref va bien)

  13. #13
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 753
    Points
    39 753
    Par défaut
    Bizarre... je soupçonnais une erreur de logique dans la boucle, mais tout a l'air OK

    L'assembly UserManager, tu l'as aussi recompilé ? en référençant bien la dernière version générée de l'assembly où IRMWorker est définie ? Je pose la question, parce que si UserManager référence une version antérieure de IRMWorker, c'est possible que loadedType.GetInterface("IRMWorker") renvoie true, mais que typeof(IRMWorker).IsAssignableFrom(loadedType) renvoie false (2 interfaces différentes avec le même nom)

  14. #14
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    125
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2007
    Messages : 125
    Points : 109
    Points
    109
    Par défaut
    ... Je suis même allé jusqu'à supprimer tout le repertoire Output pour être sur...

    C'est là que les idées "délirantes" sont les bienvenues:

    Ya forcement un truc que j'ai pas vu !!

  15. #15
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 753
    Points
    39 753
    Par défaut
    là je commence à être un peu à court d'idées

    ah si, encore un truc : fais loadedType.GetInterfaces(), regardes le nom complet du type IRMWorker implémenté par loadedType (namespace + nom, nom + version + publicKeyToken de assembly), et vérifie que ça correspond bien à typeof(IRMWorker)

    EDIT : c'est pas très clair ce que je raconte au dessus, et y a plus simple... Rajoute ça dans ton code après le "if (interf != null)" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    System.Diagnostics.Debug.WriteLine(interf.AssemblyQualifiedName);
    System.Diagnostics.Debug.WriteLine(typeof(IRMWorker).AssemblyQualifiedName);
    Et compare les 2 lignes dans la fenêtre de sortie. S'il y a une différence, ça pourrait être un début d'explication...

  16. #16
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    125
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2007
    Messages : 125
    Points : 109
    Points
    109
    Par défaut
    la (seule) interface exposée par le type 'UserManager':
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    AssemblyQualifiedName
    "RM.Service.IRMWorker, ServiceInterface, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"	string
    et l'interface de IRMWorker:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    AssemblyQualifiedName
    "RM.Service.IRMWorker, ServiceInterface, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"	string
    les GUID sont les mêmes....

    Je désespère...

  17. #17
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 753
    Points
    39 753
    Par défaut
    bon ben là je sais plus trop quoi te dire...

  18. #18
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    125
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2007
    Messages : 125
    Points : 109
    Points
    109
    Par défaut
    Bonjour,

    Je sais que vous allez me prendre pour un fou, mais:
    - Pour éviter de vérifier que chacune des DLL de mon projet contient un type qui m'interesse, j'ai changé légèrement ma politique de nommage:
    => Mon projet UserManager (qui générait "UserManager.dll") génère maintenant un "RM.Service.UserManager.dll"

    Et voilà !!

    Il load mes assemblies comme avant, mais maintenant, il veut bien instancier mes objets !
    Le plus fort ?
    C'est que ca marche aussi bien avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    object newWorker = Activator.CreateInstance(loadedType);
    IRMWorker worker = newWorker as IRMWorker;
    if (worker != null)
                  mWorkers.Add(worker);
    qu'avec

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    IRMWorker newRMWorker = (IRMWorker)Activator.CreateInstance(loadedType);
    if (newRMWorker != null)
            mWorkers.Add(newRMWorker);
    Si quelqu'un a une explication pour ce comportement, je suis preneur !!

    Je ne sais pas comment diffuser cette information plus largement (qu'il faudrait d'abord vérifier et essayer de généraliser!), mais vu le coup de stress que ça m'a mis, je voudrais éviter que d'autres en souffrent...


    Une fois de plus, merci beaucoup TomLev pour ton aide



    .. je passe le thread en résolu ... YYEEEESSSS !!!!!!

  19. #19
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 753
    Points
    39 753
    Par défaut
    Citation Envoyé par ElTchoupi Voir le message
    Je ne sais pas comment diffuser cette information plus largement (qu'il faudrait d'abord vérifier et essayer de généraliser!), mais vu le coup de stress que ça m'a mis, je voudrais éviter que d'autres en souffrent...
    Si tu es sûr que c'est un bug, tu peux le signaler à MS :
    https://connect.microsoft.com/

  20. #20
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    125
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2007
    Messages : 125
    Points : 109
    Points
    109
    Par défaut
    Citation Envoyé par tomlev Voir le message
    Si tu es sûr que c'est un bug, tu peux le signaler à MS :
    https://connect.microsoft.com/
    Je suis pas sûr du tout que ce soit un bug: je pense "maitriser" 2% des fonctionnalités de Visual Studio.... !
    Maintenant, ya clairement quelque chose qui cloche dans toute cette histoire...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. instancier une interface
    Par new_wave dans le forum Débuter
    Réponses: 2
    Dernier message: 26/04/2013, 11h30
  2. Possible d'instancier une interface ?
    Par nuriel2 dans le forum Débuter avec Java
    Réponses: 5
    Dernier message: 27/03/2010, 23h07
  3. Problème d'instanciation d'interfaces
    Par madmox dans le forum Débuter avec Java
    Réponses: 6
    Dernier message: 29/05/2007, 17h19
  4. Réponses: 6
    Dernier message: 24/08/2006, 14h33
  5. Réponses: 12
    Dernier message: 20/01/2006, 20h40

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo