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 :

Injection de dépendance et librairie dynamique (dll ou so)


Sujet :

C++

  1. #1
    Membre habitué
    Profil pro
    Dev
    Inscrit en
    Mai 2009
    Messages
    257
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Dev

    Informations forums :
    Inscription : Mai 2009
    Messages : 257
    Points : 190
    Points
    190
    Par défaut Injection de dépendance et librairie dynamique (dll ou so)
    Généralement, on utilise une librairie dynamique en "sens unique", le code principal charge la librairie et appelle les fonctions paramétrées dont il a besoin

    Mettons que l'on veuille injecter une dépendance dans cette lib (une classe du code principal par exemple), et donc inverser le contrôle, comment faut il s'y prendre ?

  2. #2
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2010
    Messages
    254
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2010
    Messages : 254
    Points : 538
    Points
    538
    Par défaut
    Je ne pense pas que ce soit possible. Voir même pas du tout. En fait ça pue limite le hack ton truc.
    "L'insanité consiste à répéter la même action dans l'espoir d'aboutir à un résultat différent" Albert Einstein
    ----------------------
    T.O.A.O 6-MarViN

  3. #3
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    Je ne saisis pas le problème. Rien ne t'empêche de donner le contrôle à ta bibliothèque. Celle-ci contient une fonction/classe d'entrée (qui prend le contrôle) et ensuite à coup de DP prototype/fabrique tu implémentes ton IoC.

    Code dll : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    class dependency
    {
    public:
       virtual ~dependency()=0;
    };
    class application
    {
    public:
        application(dependency &); // demarrage
     
    };

    Code exe : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    class my_dependency : public dependency
    {
    public:
        virtual ~my_dependency();
    };
     
    int main()
    {
       my_dependency dep;
       application app(dep); // à partir de là, ta DLL prend le contrôle
       return 0;
    }

  4. #4
    Membre habitué
    Profil pro
    Dev
    Inscrit en
    Mai 2009
    Messages
    257
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Dev

    Informations forums :
    Inscription : Mai 2009
    Messages : 257
    Points : 190
    Points
    190
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Salut,
    Je ne saisis pas le problème. Rien ne t'empêche de donner le contrôle à ta bibliothèque. Celle-ci contient une fonction/classe d'entrée (qui prend le contrôle) et ensuite à coup de DP prototype/fabrique tu implémentes ton IoC.

    Code dll : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    class dependency
    {
    public:
       virtual ~dependency()=0;
    };
    class application
    {
    public:
        application(dependency &); // demarrage
     
    };

    Code exe : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    class my_dependency : public dependency
    {
    public:
        virtual ~my_dependency();
    };
     
    int main()
    {
       my_dependency dep;
       application app(dep); // à partir de là, ta DLL prend le contrôle
       return 0;
    }
    Ok, jusque là pas de problème

    maintenant mettons que dependency a besoin de plusieurs fichiers:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    #include file1.hpp
    #include file2.hpp
    #include file3.hpp
     
    class dependency
    {
    public:
       virtual ~dependency()=0;
    };
    et que chacun de ces fichiers a besoin d'autres fichiers, etc
    au final on se retrouve avec une bonne portion de fichiers du code appellant à inclure dans la librairie
    J'aimerais savoir comment éviter ça

  5. #5
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    Déclaration anticipée ?
    De toute façon si dependency dépend d'autres classes, alors ces classes doivent être des interfaces abstraites dont l'instance concrète est injectée à la construction. Peux tu préciser plus en détail ton exemple car sinon j'ai peur de ne pas forcément tout saisir.

  6. #6
    Membre habitué
    Profil pro
    Dev
    Inscrit en
    Mai 2009
    Messages
    257
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Dev

    Informations forums :
    Inscription : Mai 2009
    Messages : 257
    Points : 190
    Points
    190
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Salut,
    Déclaration anticipée ?
    De toute façon si dependency dépend d'autres classes, alors ces classes doivent être des interfaces abstraites dont l'instance concrète est injectée à la construction. Peux tu préciser plus en détail ton exemple car sinon j'ai peur de ne pas forcément tout saisir.
    ce qui me gêne c'est que dependency.hpp doive inclure d'autres fichiers .hpp, ce qui fait que l'on déporte une bonne partie du code appelant vers la librairie.
    Code inutile pour celle-ci mais indispensable pour pour pouvoir injecter dependency
    Je voulais savoir s'il y avait moyen de contourner cette injection de fichiers non nécessaires à la librairie

  7. #7
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    Si elle utilise d'autres header, c'est que la bibliothèque en a besoin. Normalement, on devrait avoir quelque chose ressemblant à ça
    Code dll : 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
     
    class interface
    {
    public:
        void something(){do_something();}
        virtual interface();
    private:
         virtual void do_something()=0;
    };
    class dependency
    {
       dependency(interface&);
    public:
       virtual ~dependency()=0;
    };
    class application
    {
    public:
        application(dependency &); // demarrage
     
    };
    et
    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
     
    class my_interface : public interface
    {
    public:
        virtual ~my_interface();
    };
     
    class my_dependency : public dependency
    {
    public:
        my_dependency(my_interface&intf):dependency(intf){}
        virtual ~my_dependency();
    };
     
    int main()
    {
       my_interface intf;
       my_dependency dep(intf);
       application app(dep); // à partir de là, ta DLL prend le contrôle
       return 0;
    }
    La dépendance peut être injecté non pas à la construction mais éventuellement avec un DP Fabrique :
    Code dll : 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
     
    class interface
    {
    public:
        void something(){do_something();}
        virtual interface();
    private:
         virtual void do_something()=0;
    };
    class dependency
    {
       dependency();
       void int_needed()
       {
             interface& intf = getInterface();
       }
    public:
       virtual ~dependency()=0;
       virtual interface&getInterface()=0;
    };
    class application
    {
    public:
        application(dependency &dep); // demarrage
     
    };
    et
    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
     
    class my_interface : public interface
    {
    public:
        virtual ~my_interface();
    };
     
    class my_dependency : public dependency
    {
    public:
        virtual ~my_dependency();
    private:
         virtual interface&getInterface()
         {
               return intf;
         }
         my_interface intf;
    };
     
    int main()
    {
       my_dependency dep;
       application app(dep); // à partir de là, ta DLL prend le contrôle
       return 0;
    }
    Bref, si une dependency a elle même des dépendances, il faut définir les interfaces abstraites sur laquelle elle s'appuie et l'implémenter côté application. Si côté application my_dependency a des besoins transparents pour la classe de base, alors c'est dans la construction de my_dependency dans l'applicatif qu'il faut injecter ces dépendances.

    Tu peux construire un petit exemple de ce qui te pose problème car là j'ai l'impression d'avoir quelque chose qui m'échappe.

  8. #8
    Membre habitué
    Profil pro
    Dev
    Inscrit en
    Mai 2009
    Messages
    257
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Dev

    Informations forums :
    Inscription : Mai 2009
    Messages : 257
    Points : 190
    Points
    190
    Par défaut
    Tu es bien d'accord que :

    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
    class my_interface : public interface
    {
    public:
        virtual ~my_interface();
    };
     
    
    #include "my_interface.h"
    class my_dependency : public dependency
    {
    public:
        virtual ~my_dependency();
    private:
         virtual interface&getInterface()
         {
               return intf;
         }
         my_interface intf;
    };
    et que donc :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    #include "dependency.h"
    int main()
    {
       my_dependency dep;
       application app(dep); // à partir de là, ta DLL prend le contrôle
       return 0;
    }
    question déploiement on aura ainsi côté appelant :

    my_interface.h
    dependency.h

    et côté librairie :

    my_interface.h
    dependency.h

    si l'on opère des changements sur my_interface.h dans le code appelant, il faudra les répercuter dans la lib en remplaçant le fichier et en recompilant la lib; or la librairie ne s'intéresse qu'à dependency.h, pourquoi lui imposer my_interface.h ?

    ce qui m'intéresse donc c'est de savoir s'il y a moyen de n'inclure que dependency.h dans la lib même si dependency.h dépend d'autres .h

  9. #9
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Non.
    Côté DLL, on a
    • dependency.h qui défini dependency et qui inclut :
    • interface.h qui défini interface.


    Côté EXE, on a :
    • my_dependency.h qui défini my_dependency qui hérite et implémente dependency et :
    • my_interface.h qui défini my_interface qui hérite et implémente interface.


    Si my_interface évolue, c'est de façon totalement transparente pour dependency (et dependency.h). Mais peut être pas pour my_dependency (et my_dependency.h). Bref, seul ce qui est dans l'exécutable est impacté.

    A l'inverse, si interface évolue, ça peut avoir un impact sur dependency (et dependency.h) et certainement sur my_interface (et my_interface.h). Mais dans ce sens cela ne me choque pas.

    Derrière l'injection de dépendance et l'IoC il y a le socle du DIP : Dependency Inversion Principle.

Discussions similaires

  1. Réponses: 3
    Dernier message: 06/07/2011, 14h35
  2. Injection de dépendance, AOP dynamique
    Par davcha dans le forum Général Dotnet
    Réponses: 1
    Dernier message: 24/06/2010, 20h08
  3. Réponses: 7
    Dernier message: 24/11/2008, 12h49
  4. Librairie dynamique (DLL) en Borland
    Par ywan42 dans le forum Windows
    Réponses: 3
    Dernier message: 18/03/2007, 18h19
  5. Recompiler une librairie dynamique (DLL) en statique
    Par shenron666 dans le forum C++
    Réponses: 9
    Dernier message: 07/04/2005, 19h28

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