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

Dotnet Discussion :

[Article] Injection de dépendances en .NET


Sujet :

Dotnet

  1. #1
    Expert éminent sénior

    Avatar de Philippe Vialatte
    Homme Profil pro
    Architecte technique
    Inscrit en
    Juillet 2004
    Messages
    3 029
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2004
    Messages : 3 029
    Points : 12 465
    Points
    12 465
    Par défaut [Article] Injection de dépendances en .NET
    Cette discussion est consacrée à l'article intitulé "Injection de dépendances en .NET, pattern, intérêt et outils"

    Dans cet article, on va voir ce qu'est l'injection de dépendances, son intérêt, et les outils permettant de la mettre en œuvre.

    Vous pouvez y poster vos commentaires concernant l'article.

    L'article se trouve à l'adresses suivante :
    http://philippe.developpez.com/artic...dedependances/

    Mon Blog

    The Cake is still a lie !!!



    Vous voulez contribuer à la rubrique .NET ? Contactez-moi par MP.
    Vous voulez rédiger des articles pour la rubrique .NET ? Voici la procédure à suivre.

  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 : 42
    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 749
    Points
    39 749
    Par défaut
    Très intéressant tout ça, ça me donne des idées pour la nouvelle archi de l'appli que je développe au boulot

    Petite question : j'entends pas mal parler de Castle Windsor, mais je ne le vois pas dans ta liste de containers IoC. Tu l'as déjà utilisé ? Qu'est-ce qu'il vaut par rapport aux autres ?

  3. #3
    Expert éminent sénior

    Avatar de Philippe Vialatte
    Homme Profil pro
    Architecte technique
    Inscrit en
    Juillet 2004
    Messages
    3 029
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2004
    Messages : 3 029
    Points : 12 465
    Points
    12 465
    Par défaut
    Citation Envoyé par tomlev Voir le message
    Petite question : j'entends pas mal parler de Castle Windsor, mais je ne le vois pas dans ta liste de containers IoC. Tu l'as déjà utilisé ? Qu'est-ce qu'il vaut par rapport aux autres ?
    Alors, j'en ai effectivement entendu parler, mais je ne m'en suis jamais servi...
    Tu trouveras plus d'infos ici :
    http://msdn.microsoft.com/en-us/library/aa973811.aspx

    Il y'a aussi AutoFac, et deux ou trois autres frameworks que je n'ai pas inclus dans la liste.

    Personnellement, je reste convaincu par StructureMap, mais si il faut switcher, j'irais probablement voir du coté d'AutoFac -> http://code.google.com/p/autofac/

    Dans l'ensemble, je préfère initialiser tout dans le code, avec des interfaces fluides ou des lambdas

    Mon Blog

    The Cake is still a lie !!!



    Vous voulez contribuer à la rubrique .NET ? Contactez-moi par MP.
    Vous voulez rédiger des articles pour la rubrique .NET ? Voici la procédure à suivre.

  4. #4
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    C'est dommage que les déclarations xml ne soient pas les plus simples.
    C'est dommage d'avoir à recompiler si le besoin se fait d'avoir à changer l'implémentation résolue après une livraison.
    Sinon, article intéressant

  5. #5
    Expert éminent sénior

    Avatar de Philippe Vialatte
    Homme Profil pro
    Architecte technique
    Inscrit en
    Juillet 2004
    Messages
    3 029
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2004
    Messages : 3 029
    Points : 12 465
    Points
    12 465
    Par défaut
    Citation Envoyé par nico-pyright(c) Voir le message
    C'est dommage que les déclarations xml ne soient pas les plus simples.
    C'est dommage d'avoir à recompiler si le besoin se fait d'avoir à changer l'implémentation résolue après une livraison.
    C'est clair...c'est pour cela que je prefere structuremap, c'est encore le plus light a configurer en XML...

    Sinon, article intéressant
    Merci

    Mon Blog

    The Cake is still a lie !!!



    Vous voulez contribuer à la rubrique .NET ? Contactez-moi par MP.
    Vous voulez rédiger des articles pour la rubrique .NET ? Voici la procédure à suivre.

  6. #6
    Membre expérimenté Avatar de Arthis
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    1 265
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : Italie

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 265
    Points : 1 352
    Points
    1 352
    Par défaut
    Merci Philippe pour ces deux articles (SOLID et celui ci).

    Lecture très intéressante... Malheureusement, ces concepts ne font pas toujours l'unanimité dans la "vraie vie", a cause des collègues ou encore de la nature même des développements.

    Je travaille actuellement dans une agence web qui ne fait que des sites webs promotionnels, donc à durée de vie très courte (2-3 mois généralement). C'est du site web jetable. Je leur ai présente un site web modèle avec séparation en couche service, model, donnée, des interfaces, et injection de dépendance par le constructeur.

    Résultat, il ont tout rejeté arguant qu'ils ne veulent pas modifier le code à 30 endroits quand ils veulent ajouter une fonction que le client veut à la dernière minute.

    N'y a t'il pas à ton avis une certaine masse critique qui justifierait l'emploi de ces façons de faire? Cela serait intéressant de mettre des chiffres la dessus d'ailleurs.. je ne sais pas si de la littérature existe à ce sujet..

  7. #7
    Expert éminent sénior

    Avatar de Philippe Vialatte
    Homme Profil pro
    Architecte technique
    Inscrit en
    Juillet 2004
    Messages
    3 029
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2004
    Messages : 3 029
    Points : 12 465
    Points
    12 465
    Par défaut
    Malheureusement, pour les agences web et les sites jetables, c'est souvent difficile a vendre...

    La plupart du temps, utiliser des patterns et coder proprement a surtout une incidence sur la maintenance, qui represente la majorite du cout d'un site, et sur la facilite d'implementation de nouvelles fonctionnalites

    Si le site n'existe que 2 mois, le cout de mise en place peut effectivement etre demesure.

    Pour "vendre" l'idee, le mieux pourrait etre de faire un "squelette" de site web, qui pars de bonnes pratiques, et de s'en servir comme base (pour les 80% de socle commun), et de coder les 20% de spécifique par dessus.

    Mon Blog

    The Cake is still a lie !!!



    Vous voulez contribuer à la rubrique .NET ? Contactez-moi par MP.
    Vous voulez rédiger des articles pour la rubrique .NET ? Voici la procédure à suivre.

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    652
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 652
    Points : 730
    Points
    730
    Par défaut
    Citation Envoyé par Philippe Vialatte Voir le message
    Cette discussion est consacrée à l'article intitulé "Injection de dépendances en .NET, pattern, intérêt et outils"
    Juste un petit pinaillage, histoire de mériter le pseudo :)

    L'acronyme indiqué pour l'inversion de dépendance (le principe) est DI, alors que c'est l'acronyme de Dependency Injection (le pattern). Le principe d'inversion de dépendance, c'est DIP.

    Mis à part ça rien à redire, je vais jeter un oeil sur StructureMap du coup :)
    Be wary of strong drink.
    It can make you shoot at tax collectors, and miss.

  9. #9
    Expert éminent sénior

    Avatar de Philippe Vialatte
    Homme Profil pro
    Architecte technique
    Inscrit en
    Juillet 2004
    Messages
    3 029
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2004
    Messages : 3 029
    Points : 12 465
    Points
    12 465
    Par défaut
    L'acronyme indiqué pour l'inversion de dépendance (le principe) est DI, alors que c'est l'acronyme de Dependency Injection (le pattern). Le principe d'inversion de dépendance, c'est DIP.
    Pas faux

    Faut que je note de el modifier, tiens

    Sinon, c'est marrant, dans la foulee du message dÁrthis, voir les posts suivants :
    http://www.joelonsoftware.com/items/2009/09/23.html
    http://blog.objectmentor.com/article...ape-programmer
    http://jeffreypalermo.com/blog/debun...pe-programmer/
    http://www.rgoarchitects.com/nblog/2...rogrammer.aspx

    Mon Blog

    The Cake is still a lie !!!



    Vous voulez contribuer à la rubrique .NET ? Contactez-moi par MP.
    Vous voulez rédiger des articles pour la rubrique .NET ? Voici la procédure à suivre.

  10. #10
    Membre habitué
    Inscrit en
    Décembre 2003
    Messages
    108
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Décembre 2003
    Messages : 108
    Points : 129
    Points
    129
    Par défaut
    Merci pour l'article.
    C'est une technique que j'utilise depuis longtemps dans mes dev, mais n'étant pas très portée sur la théorie j'en ignorais le nom...
    J'ai utilisé cette façon de faire car c'est venu tout seul et en plus ca m'évite la redondance de code.
    En tout cas merci pour les infos

  11. #11
    Membre régulier
    Profil pro
    Inscrit en
    Août 2003
    Messages
    59
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 59
    Points : 80
    Points
    80
    Par défaut 7 ans plus tard, dans l'univers de l'injection de dépendance
    Bonjour,

    7 ans plus tard, j'imagine que cet article est encore en forte visibilité des développeurs de passage, qui se basent probablement dessus pour faire le choix de leur conteneur IoC.
    Mais aujourd'hui, est-il toujours valable ? Comment ont évolué ces conteneurs ? Certains ont-ils disparu ? Ou au contraire gagné en maturité ?

    Par exemple faut-il toujours, avec Spring.Net, utiliser à la fois un cast et une magic string pour accéder à une instance ? (ce que je trouve aberrant, ça ne passerait jamais les revues de code chez nous !).
    Bref, ce serait super si quelqu'un pouvait actualiser cet article. Si vous avez aussi des retours d'expérience sur l'un et l'autre ce serait aussi super de les poster ici (à noter : pour moi juste dire "ça marche bien chez nous" c'est pas vraiment un retour d'expérience hein !).

    Au plaisir de vous lire...

    PS : Personnellement j'ai toujours eu du mal à comprendre l’intérêt de ces conteneurs : ça fait longtemps qu'on fait de l'injection de dépendances chez nous, et on n'a pas utilisé pour autant un composant externe. Alors quand un auditeur écrit noir sur blanc dans son rapport "il n'y pas de technique d'IOC sur le projet étant donné qu'il n'y a aucune référence à Ninject ou Spring.Net", et qu'il rajoute un lien vers l'article de developpez.com, on se dit juste qu'il n'a rien compris ! Et en plus après il faut aller expliquer à votre DG que l'auditeur est un boulet...

  12. #12
    Membre éclairé
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    652
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 652
    Points : 730
    Points
    730
    Par défaut
    Ah tiens, ça faisait longtemps que je n'étais plus passé. Apparemment j'étais abonné à ce topic :)

    De mon côté... 6 ans et demi après donc, je suis toujours avec StructureMap. Ça gère très bien le peu que je lui demande, à savoir regrouper au même endroit la config des diverses dépendances. Dans le cas d'ASP.NET MVC, entre l'intégration à la pipeline pour créer les contrôleurs (et donc tout le reste) et les "sous-containers" correspondant aux requêtes (et qui appellent Dispose proprement si nécessaire ensuite), ça me va.

    Et forcément, ni cast ni magic string, tout au plus un GetService<T> pour les rares cas où il y a besoin d'y accéder directement (notamment les action filters qui ne sont pas créés via le dependency resolver normal parce que ce serait trop simple sinon...)

    Citation Envoyé par jyl2002 Voir le message
    PS : Personnellement j'ai toujours eu du mal à comprendre l’intérêt de ces conteneurs : ça fait longtemps qu'on fait de l'injection de dépendances chez nous, et on n'a pas utilisé pour autant un composant externe. Alors quand un auditeur écrit noir sur blanc dans son rapport "il n'y pas de technique d'IOC sur le projet étant donné qu'il n'y a aucune référence à Ninject ou Spring.Net", et qu'il rajoute un lien vers l'article de developpez.com, on se dit juste qu'il n'a rien compris ! Et en plus après il faut aller expliquer à votre DG que l'auditeur est un boulet... :weird:
    Been there done that :)

    Dans mon cas donc, l'intérêt est une bête histoire de facilité pour le paramétrage. Pas la peine de s'embêter à recoder le nécessaire quand il y a déjà une petite librairie dispo qui le fait très bien, intégrée au framework et qui ne ramène pas 50 packages NuGet inutiles. Et le fait que je tourne essentiellement sur ASP.NET y est pour beaucoup vu qu'il y a du coup à gérer les dépendances au niveau application et au niveau de chaque requête (e.g. sessionfactory NHibernate pour l'appli, session/transaction NHibernate pour chaque requête). Aucun accès à StructureMap ailleurs que dans la config initiale.

    Pour une appli 'normale', à moins d'avoir vraiment bcp d'instances à injecter avec des cycles de vie différents et/ou des conditions particulières pour créer les instances, l'intérêt se réduit d'un grand coup.

    Au final, l'important est l'injection de dépendances. Que ce soit fait à la main ou via une librairie, c'est juste un détail d'implémentation. Si une librairie peut simplifier la vie dans le cas du projet en question, zog zog. S'il n'y en a pas besoin, encore mieux, ça fait toujours un package de moins.

    Et l'important de juste après est surtout de ne pas utiliser ces librairies en tant que service locator, en les appelant directement à plein d'endroits pour récupérer des instances de tout et n'importe quoi. Là ce n'est plus de l'injection de dépendances mais ça devient très similaire à de l'utilisation de variables globales. Et on sait ce que ça vaut :)
    Be wary of strong drink.
    It can make you shoot at tax collectors, and miss.

  13. #13
    Candidat au Club
    Inscrit en
    Avril 2010
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 3
    Points : 3
    Points
    3
    Par défaut Question / Problème urgent
    Désolé de remonter un vieux sujet, mais j'ai une question très urgente concernant le tuto :

    Maîtrisant plutôt les notions de POO. Je viens de me lancer dans l'étude du patron : injection de dépendances.

    Votre premier exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    public class CustomerService
    {
    	public Customer GetOneCustomer(int customerId)
    	{
    	   CustomerRepository _repository = new CustomerRepository();
    	   return new Customer(_repository.GetOneById(customerId));
    	}
    }

    D'après le tuto, pour appliquer l'injection de dépendance ici, on doit appliquer les modifications suivantes :

    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
     
    public class CustomerService
    {
    	private CustomerRepository _repository;
     
    	// Modif 1 : Nouveau mutateur
    	public CustomerRepository Repository {
    		set{ _repository = value; }
    	}
     
    	public Customer GetOneCustomer(int customerId)
    	{
    	   // Modif 2 : On retire la création d'un CustomerRoepository, mais ne doit-il pas être créé ailleurs ? Alors où ??
    	   return new Customer(_repository.GetOneById(customerId));
    	}
    }
    Concernant la version modfiée :

    En appelant GetOneCustomer, je vais forcément me retrouver avec un null ref exception puisque l'objet _repository n'est jamais créé.

    La question est simple : Où crée t-on l'attribut _repository ?

    ... en plus ici on n'accède même pas au mutateur puisqu'on ne fait que lire l'attribut _repository.

    C'est assez urgent. À l'avance, merci pour votre aide

  14. #14
    Membre actif
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Septembre 2008
    Messages
    176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Analyste Programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 176
    Points : 297
    Points
    297
    Par défaut
    Bonjour,

    C'est écrit dans l'article :
    II-A. Injection par une propriété
    II-A-2. Avantages & Inconvénients
    [...]
    Il faut donc s'assurer systématiquement que toutes les dépendances soient correctement initialisées, ce qui ajoute au choix, des tests supplémentaires dans le code et/ou de la documentation sur ces fonctionnalités, et, de façon générale, du travail supplémentaire.
    En gros, avec une injection par propriété, il faut t'assurer que la propriété (Repository) soit initialisée avant d'appeler GetOneCustomer.

    Bonne continuation.
    L’aléatoire n’existe pas en informatique, c’est juste un moyen de dire que l’on a pas encore compris.

  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 : 42
    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 749
    Points
    39 749
    Par défaut
    Alors déjà, passe plutôt ta dépendance par le constructeur, c'est plus propre et plus sûr. L'injection par propriété est généralement à éviter à moins d'avoir une très bonne raison.

    Code C# : 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
     
    public class CustomerService
    {
            // Modif 1 : champ _repository initialisé par le constructeur
    	private readonly CustomerRepository _repository;
            public CustomerService(CustomerRepository repository)
            {
                _repository = repository;
            } 
     
    	public Customer GetOneCustomer(int customerId)
    	{
    	   // Modif 2 : On retire la création d'un CustomerRoepository, mais ne doit-il pas être créé ailleurs ? Alors où ??
    	   return new Customer(_repository.GetOneById(customerId));
    	}
    }

    Maintenant, pour créer une instance de CustomerService, il faut lui passer une instance de CustomerRepository. Soit tu le fais manuellement à l'endroit où tu crées le service :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var customerRepository = new CustomerRepository();
    var customerService = new CustomerService(customerRepository);

    Soit tu passes par un conteneur IoC (Unity dans mon exemple ci-dessous) :

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    var container = new UnityContainer();
    container.RegisterType<CustomerRepository>();
    container.RegisterType<CustomerService>();
    ...
    var customerService = container.Resolve<CustomerService>(); // crée automatiquement le CustomerService en lui passant un CustomerRepository, lui aussi créé automatiquement

  16. #16
    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 : 42
    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 749
    Points
    39 749
    Par défaut
    Pour répondre à ta question :

    Citation Envoyé par Squall-25 Voir le message
    En appelant GetOneCustomer, je vais forcément me retrouver avec un null ref exception puisque l'objet _repository n'est jamais créé.

    La question est simple : Où crée t-on l'attribut _repository ?

    ... en plus ici on n'accède même pas au mutateur puisqu'on ne fait que lire l'attribut _repository.
    Le principe même de l'injection de dépendances, c'est que ce n'est pas la classe qui crée ses propres dépendances, elle les reçoit de l'extérieur. Donc c'est le code qui crée le service qui doit fournir le repository. Si tu tiens à utiliser une propriété (ce que je déconseille, cf. mon message précédent), ça ressemblera à ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var customerService = new CustomerService();
    customerService.Repository = new CustomerRepository();
    L'intérêt de cette approche est que tu réduis le couplage entre une classe et ses dépendances. De cette façon, CustomerService n'a pas besoin de connaitre une implémentation spécifique de CustomerRepository, il prend juste celle qu'on lui fournit.

    Par contre, pour que ça ait vraiment un intérêt, il faudrait que CustomerService dépende d'une abstraction de CustomerRepository, par exemple une interface ICustomerRepository.

Discussions similaires

  1. [Débutant] [VB.NET] Injection de dépendances
    Par shurikeNzL dans le forum VB.NET
    Réponses: 2
    Dernier message: 07/01/2012, 15h30
  2. Réponses: 14
    Dernier message: 09/09/2011, 19h15

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