Enterprise Library Unity vs autres conteneurs IoC [fermé]


135

Quels sont les avantages et les inconvénients de l'utilisation de Enterprise Library Unity par rapport aux autres conteneurs IoC (Windsor, Spring.Net, Autofac ..)?


9
Ces types de questions sont toujours fermés. Les opinions sont importantes. Y a-t-il un endroit où les placer?
Jeson Martajaya

1
@JesonMartajaya, je voulais féliciter exactement le même commentaire, c'est ennuyeux que les questions se referment, mais pas de réponse pour une alternative.
Mohammed Noureldin

Réponses:


234

Je prépare une présentation pour un groupe d'utilisateurs. En tant que tel, je viens de passer par un tas d'entre eux. À savoir: AutoFac, MEF, Ninject, Spring.Net, StructureMap, Unity et Windsor.

Je voulais montrer le cas à 90% (injection de constructeur, qui est principalement ce pour quoi les gens utilisent un CIO de toute façon). Vous pouvez consulter la solution ici (VS2008)

En tant que tel, il existe quelques différences clés:

  • Initialisation
  • Récupération d'objets

Chacun d'eux a également d'autres fonctionnalités (certains ont AOP et de meilleurs gizmos, mais en général, tout ce que je veux qu'un IOC fasse, c'est créer et récupérer des objets pour moi)

Remarque: les différences entre les différentes récupérations d'objets de bibliothèques peuvent être annulées en utilisant CommonServiceLocator: http://www.codeplex.com/CommonServiceLocator

Cela nous laisse avec l'initialisation, qui se fait de deux manières: via le code ou via la configuration XML (app.config / web.config / custom.config). Certains prennent en charge les deux, certains n'en supportent qu'un. Je devrais noter: certains utilisent des attributs pour aider l'IoC.

Voici donc mon évaluation des différences:

Ninject

Initialisation du code uniquement (avec attributs). J'espère que vous aimez les lambdas. Le code d'initialisation ressemble à ceci:

 IKernel kernel = new StandardKernel(
                new InlineModule(
                    x => x.Bind<ICustomerRepository>().To<CustomerRepository>(),
                    x => x.Bind<ICustomerService>().To<CustomerService>(),
                    x => x.Bind<Form1>().ToSelf()
                    ));

StructureMap

Code d'initialisation ou XML ou attributs. La v2.5 est également très lambda'y. Dans l'ensemble, c'est l'un de mes préférés. Quelques idées très intéressantes sur la façon dont StructureMap utilise les attributs.

ObjectFactory.Initialize(x =>
{
    x.UseDefaultStructureMapConfigFile = false;
    x.ForRequestedType<ICustomerRepository>()
        .TheDefaultIsConcreteType<CustomerRepository>()
        .CacheBy(InstanceScope.Singleton);

    x.ForRequestedType<ICustomerService>()
        .TheDefaultIsConcreteType<CustomerService>()
        .CacheBy(InstanceScope.Singleton);

    x.ForConcreteType<Form1>();
 });

Unité

Code d'initialisation et XML. Belle bibliothèque, mais la configuration XML est une douleur dans le cul. Grande bibliothèque pour Microsoft ou les magasins d'autoroute. L'initialisation du code est simple:

 container.RegisterType<ICustomerRepository, CustomerRepository>()
          .RegisterType<ICustomerService, CustomerService>();

Spring.NET

XML seulement aussi près que je peux le dire. Mais pour la fonctionnalité, Spring.Net fait tout ce qu'un IoC peut faire sous le soleil. Mais comme le seul moyen de s'unifier est via XML, il est généralement évité par les boutiques .net. Cependant, de nombreux magasins .net / Java utilisent Spring.Net en raison de la similitude entre la version .net de Spring.Net et le projet Java Spring.

Remarque : la configuration dans le code est désormais possible avec l'introduction de Spring.NET CodeConfig .

Windsor

XML et code. Comme Spring.Net, Windsor fera tout ce que vous voudrez qu'elle fasse. Windsor est probablement l'un des conteneurs IoC les plus populaires.

IWindsorContainer container = new WindsorContainer();
container.AddComponentWithLifestyle<ICustomerRepository, CustomerRepository>("CustomerRepository", LifestyleType.Singleton);
container.AddComponentWithLifestyle<ICustomerService, CustomerService>("CustomerService",LifestyleType.Singleton);
container.AddComponent<Form1>("Form1");

Autofac

Peut mélanger XML et code (avec v1.2). Belle bibliothèque IoC simple. Semble faire les bases sans trop de bruit. Prend en charge les conteneurs imbriqués avec une portée locale des composants et une gestion de la durée de vie bien définie.

Voici comment vous l'initialisez:

var builder = new ContainerBuilder();
builder.Register<CustomerRepository>()
        .As<ICustomerRepository>()
        .ContainerScoped();
builder.Register<CustomerService>()
        .As<ICustomerService>()
        .ContainerScoped();
builder.Register<Form1>();

Si je devais choisir aujourd'hui: j'irais probablement avec StructureMap. Il offre le meilleur support pour les fonctionnalités du langage C # 3.0 et la plus grande flexibilité dans l'initialisation.

Remarque : Chris Brandsma a transformé sa réponse originale en un article de blog .


1
Configuration XML uniquement, ce qui rend la configuration beaucoup plus difficile. Fondamentalement, les seules personnes que je vois qui souhaitent utiliser Spring.Net sont d'anciens développeurs Java.
Chris Brandsma

Chris, concernant vos conclusions: pouvez-vous donner plus de détails sur a) à quelles fonctionnalités C # 3 vous faites référence, et b) à quels types d'initialisation sont importants pour vous? Merci!
Nicholas Blumhardt

2
Salut Nicholas: en ce qui concerne le support C # 3, tout ce qu'Autofac fait déjà. :) Pour l'initialisation, je veux un support facile pour les singletons / non singletons, et l'initialisation par session. Enfin, je veux des moyens faciles de référencer par un nom personnalisé. (quelque chose qui est un PITA dans StructureMap). La dernière fonctionnalité que j'aime plus maintenant que lorsque j'ai écrit ceci à l'origine: AutoMocking. Je ne l'utilise pas tout le temps, mais c'est très agréable d'en avoir un.
Chris Brandsma

Vous avez également mentionné MEF, j'utilise MEF pour fournir mes objets d'implémentation IRepository et je trouve que cela fonctionne très bien. Que pensez-vous du MEF?
terjetyl

Voici un joli screencast de 20 minutes présentant la plupart de Unity: pnpguidance.net/Screencast
Pat

7

Pour autant que j'ai vu, ils sont à peu près les mêmes, à l'exception de quelques détails d'implémentation ici et là. Le plus grand avantage d'Unity par rapport à la concurrence est qu'il est fourni par Microsoft, il y a beaucoup d'entreprises qui ont peur des OSS.

Un inconvénient est qu'il est plutôt nouveau et qu'il peut donc y avoir des bugs que les anciens joueurs ont déjà résolus.

Cela dit, vous voudrez peut-être vérifier cela .


4

Ancien fil mais puisque c'est la première chose que Google m'a montré quand j'ai tapé unité vs spring.net ...

Spring fait CodeConfig maintenant si vous n'aimez pas la configuration XML

http://www.springframework.net/codeconfig/doc-latest/reference/html/

De plus, Spring est bien plus qu'un simple conteneur DI, si vous regardez la section `` Modules '' dans la documentation, le conteneur DI est le fondement de l'énorme pile de choses qu'il fait.


3

Corrigez-moi si je me trompe mais je pense qu'Autofac lui-même prend en charge la configuration XML comme indiqué dans ce lien: Configuration XML d'Autofac


2

Spring a une fonctionnalité qui permet d'injecter des paramètres au constructeur ou à la propriété en fonction du nom ou de la position du paramètre. Ceci est très utile si le paramètre ou la propriété est de type simple (par exemple un entier, un booléen). Voir l'exemple ici . Je ne pense pas que cela compense vraiment l'incapacité de Spring à faire la configuration dans le code.

Windsor peut également le faire, et peut le faire en code non config. (corrigez-moi si je me trompe, je passe simplement par ce que j'ai entendu ici).

J'aimerais savoir si Unity peut le faire.



1

Juste pour ajouter mes 2 cents, j'ai essayé à la fois StructureMap et Unity. J'ai trouvé que StructureMap était mal / mal documenté, difficile à configurer et maladroit à utiliser. De même, il ne semble pas prendre en charge les scénarios tels que les remplacements d'arguments du constructeur au moment de la résolution, ce qui était un point d'utilisation clé pour moi. Je l'ai donc laissé tomber et je suis allé avec Unity, et je l'ai fait faire ce que je voulais en environ 20 minutes.


1

J'utilise personnellement Unity, mais uniquement parce qu'il provient de Microsoft. Je regrette la décision pour une raison: la plus grande chose qu'il a contre elle a un gros "bogue" qui le pousse à lancer constamment des exceptions. Vous pouvez ignorer les exceptions lors du débogage. Cependant, cela ralentit énormément votre application si vous la rencontrez, car lancer une exception est une opération coûteuse. Par exemple, je "corrige" actuellement cette exception à un endroit de mon code où les exceptions d'Unity ajoutent 4 secondes supplémentaires au temps de rendu d'une page. Pour plus de détails et une solution de contournement, voir:

Unity peut-il être obligé de ne pas lancer une exception SynchronizationLockException tout le temps?


Merci pour l'avertissement! D'après cette réponse à la question à laquelle vous vous êtes référé , le bogue est maintenant résolu.
Sam

Pourquoi Unity lève-t-il une exception? Habituellement, une exception est une «erreur critique» (telle qu'une dépendance irréversible) et non quelque chose à supprimer ..
user2864740

Excusez-moi, ce "bug" est-il résolu ou avez-vous trouvé un moyen de l'éviter? Je choisis le framework en c # .net maintenant et je suis impatient de savoir si l'unité est toujours coûteuse en temps ...
Jog Dan
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.