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#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    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
    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
    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 Expert
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    826
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2006
    Messages : 826
    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
    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 Expert
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    826
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2006
    Messages : 826
    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
    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

+ 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