web-dev-qa-db-fra.com

Exemples de conteneurs IoC

Quelqu'un a-t-il de bons exemples de conteneurs IoC (de préférence en c #) et comment et pourquoi les utiliser? J'ai vérifié l'exemple page wiki et Ayende , mais je n'ai pas encore tout à fait compris le concept.

Et quand et où dois-je utiliser un conteneur IoC?

44
Morph

J'ai utilisé StructureMap un peu. Le reste de votre question est assez chargé. Je vais essayer d'expliquer le concept dans un exemple.

Supposons que vous ayez créé un site Web qui acceptera les paiements via Paypal. Paypal est désormais une dépendance. Mais vous ne voulez pas coder contre un fournisseur Paypal spécifique.

Au lieu de cela, vous créeriez et coderiez contre une interface comme celle-ci:

interface IPaymentProcessor
{
    bool ProcessPayment(amount, ....);
}

Tout votre code Paypal résiderait dans une classe qui implémente les méthodes de votre interface - PayPalPaymentProcessor, par exemple.

Vous disposez maintenant d'un objet que vous allez réellement utiliser pour traiter les paiements. Il peut s'agir d'un contrôleur (ASP.NET-MVC, ViewModel-WPF) ou simplement d'une classe comme indiqué ici:

class PaymentProcessor
{
    private IPaymentProcessor _processor = null;
    public PaymentProcessor(IPaymentProcessor processor)
    {
        _processor = processor;
    }

    public bool ProcessTransaction(Transaction trans)
    {
       _processor.ProcessPayment(trans.amount, ...);
    }
}

C'est là qu'intervient un conteneur IoC. Au lieu d'appeler le constructeur manuellement, vous laisseriez un conteneur IoC injecter la dépendance:

PaymentProcessor processor = ObjectFactory.GetInstance<PaymentProcessor>();

Ce morceau de code indique à StructureMap "Chaque fois que vous voyez un constructeur qui a besoin d'un IPaymentProcessor, renvoyez un nouveau PayPalPaymentProcessor".

ObjectFactory.Initialize(x =>
{ 
    x.ForRequestedType<IPaymentProcessor>().TheDefaultIsConcreteType<PayPalPaymentProcessor>();
});

Tout ce mappage est distinct de votre code d'implémentation et vous pouvez les échanger ultérieurement avec peu de refactorisation nécessaire. Il y a beaucoup plus dans les conteneurs IoC, mais c'est le concept de base. Vous pouvez automatiser l'injection de constructeurs pour éviter également les appels directement à ObjectFactory.

J'espère que cela t'aides!

56
Jab

Soyez conscient des limites suivantes du conteneur IOC. Je dois avertir les gens, car je vis avec l'enfer d'avoir à prendre en charge un système qui l'utilise:

  • Les exceptions levées par les constructeurs sont avalées. Vous obtenez uniquement l'exception "impossible de créer une dépendance". Cela signifie que vous ne pouvez pas intercepter les exceptions attendues s'il s'agit d'un constructeur.
  • Impossible de parcourir les constructeurs.
  • Oublier d'enregistrer une interface s'interrompt lors de l'exécution au lieu de la compilation.
  • Toutes vos classes ne peuvent avoir qu'un seul constructeur et elles doivent toutes accepter des interfaces comme paramètres.
  • Toutes les dépendances sont instanciées de sorte que vous ne pouvez pas partager d'instances, ce qui signifie que votre utilisation de la mémoire peut augmenter rapidement.
  • Il favorise de nombreuses interdépendances qui peuvent masquer le fait que votre code s'est transformé en spaghetti. Le fait de faciliter l'instauration de toutes ces interdépendances masque simplement qu'il existe un problème sous-jacent potentiel.
  • Vous ne pouvez pas gérer votre propre "unité de travail" très facilement car vous ne pouvez pas gérer une transaction sur plusieurs dépendances, car vous n'aviez pas le contrôle de les instancier et de passer dans le contexte de cette transaction.

Ne vous méprenez pas, j'adore l'injection de dépendances et l'inversion du principe de contrôle, mais je pense que le conteneur IOC pourrait être utilisé de manière responsable, mais soyez conscient des batailles que vous devrez se battre à cause de la liste ci-dessus.

23
Dannie

Si vous voulez voir un conteneur IoC sous le capot, et aussi le point (injection de dépendance), il y a un super podcast sur DNR TV ( Episode 126 ) qui va vraiment en détail sur la façon de les créer, pourquoi vous en auriez besoin. C'est un podcast vraiment merveilleux. Une fois que vous avez regardé cette vidéo, vous pourrez alors regarder nity , Ninject , StructureMap , etc. et être en mesure de comprendre ce qu'ils font

8
Joseph

Découvrez Spring IoC (.net) un conteneur Java/.net. La documentation est une assez bonne introduction.

En bref: vous pouvez considérer l'IoC comme une architecture qui encourage: la composition des objets et la programmation vers une interface .

Cela vous donne les éléments suivants:

  • la possibilité de tester votre code unitaire facilement (vous pouvez facilement tester vos objets de manière isolée en simulant toutes ses dépendances).

  • Une configuration extrêmement avancée (car votre programme avec IoC n'est qu'un tas d'objets et une configuration qui colle les objets ensemble).

  • La possibilité d'étendre ou de modifier une application compilée en octets (cela est vrai pour Java Je ne sais pas si c'est vrai pour .net).

3
Piotr Czapla

Nous utilisons Ninject en raison de son API simple et de sa résolution rapide des objets. Il est très bien documenté et exploite des fonctionnalités C # 3.0 telles que les expressions lambda pour faciliter la spécification.

Vous pouvez trouver plusieurs screencasts sur Ninject ici

2
Jeffrey Cameron

Essayez-vous de créer un conteneur IoC pourquoi ne pas utiliser l'un des conteneurs disponibles comme Spring.NET, StructureMap ou Unity Application Block? ici est une liste de projets IoC open source

1
Satish

J'utilise normalement StructureMap - principalement parce que je connais la syntaxe. J'ai également entendu de bonnes choses à propos de autofac et j'ai hâte d'essayer Ninject quand il atteindra la v2.

Vous voudrez peut-être jeter un oeil à cette réponse où je parle d'une utilisation de base d'un conteneur IoC (je pense toujours que les choses sont plus faciles à comprendre avec un exemple simple) - qui pourraient vous aider à comprendre les choses un peu plus. Fondamentalement, le conteneur IoC vous aide à créer des objets avec toutes les dépendances satisfaites et vous permet de modifier vos dépendances avec un code de configuration minimal.

1
Steve Willcock

Essayez de lire Introduction à Unity Application Block et dans ASP.NET StoreFront: Dependency Injection screencast, vous pouvez en savoir plus sur les concepts de Dependency Injection.

1
Jozef Izso

J'utilise Unity pour mon conteneur IoC, mais la différence entre les conteneurs réside dans plus que ce que vous pouvez faire avec DI.

DI (Dependency Injection) est principalement un moyen d'obtenir un couplage plus lâche entre les parties disparates de votre programme. Donc, si vous avez écrit un jeu qui vous plaît comment cela fonctionne, en utilisant DI, vous pouvez changer les personnages ou le moteur physique dans le jeu sans changer d'autres parties du jeu, donc, si quelqu'un paie plus d'argent, il obtient le moteur le plus réaliste, ou les meilleurs caractères, mais comme rien d'autre ne change, le test est plus simple.

Le test unitaire est également plus facile avec DI car vous pouvez simuler la base de données, par exemple, en changeant simplement l'implémentation qui sera utilisée par l'application, sans affecter quoi que ce soit d'autre.

Si vous utilisez Spring.NET par exemple, vous aurez accès à un cadre très puissant, mais il peut faire beaucoup que vous n'utiliserez pas, alors recherchez quelque chose de plus petit. Je pense que la meilleure règle est de trouver la mise en œuvre la plus petite et la plus simple qui répond à vos besoins, et de l'utiliser.

0
James Black