Quels sont les avantages et les inconvénients de l'utilisation d'Enterprise Library Unity par rapport aux autres conteneurs IoC (Windsor, Spring.Net, Autofac ..)?
Je prépare une présentation pour un groupe d'utilisateurs. En tant que tel, je viens d'en parcourir un tas. À savoir: AutoFac, MEF, Ninject, Spring.Net, StructureMap, Unity et Windsor.
Je voulais montrer le cas à 90% (injection de constructeur, qui est principalement ce que les gens utilisent un IOC pour de toute façon). Vous pouvez consulter la solution ici (VS2008) =
À ce titre, il existe quelques différences clés:
Chacun d'eux a également d'autres fonctionnalités (certains ont AOP et de meilleurs gadgets, mais généralement tout ce que je veux, c'est un IOC à faire est de créer et de récupérer des objets pour moi))
Remarque: les différences entre la récupération d'objet de différentes 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 soutiennent les deux, certains n'en soutiennent qu'un. Je devrais noter: certains utilisent des attributs pour aider l'IoC.
Voici donc mon évaluation des différences:
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()
));
Code d'initialisation ou XML ou Attributs. v2.5 est également très lambda'y. Dans l'ensemble, c'est l'un de mes favoris. 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>();
});
Code d'initialisation et XML. Belle bibliothèque, mais la configuration XML est pénible. Grande bibliothèque pour Microsoft ou les magasins d'autoroute. L'initialisation du code est simple:
container.RegisterType<ICustomerRepository, CustomerRepository>()
.RegisterType<ICustomerService, CustomerService>();
XML aussi proche que possible. Mais pour les fonctionnalités, Spring.Net fait tout sous le soleil qu'un IoC peut faire. Mais parce que le seul moyen de s'unir est via XML, il est généralement évité par les boutiques .net. Cependant, de nombreuses boutiques .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 .
XML et code. Comme Spring.Net, Windsor fera tout ce que vous pourriez souhaiter. 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");
Peut mélanger XML et code (avec v1.2). Belle bibliothèque IoC simple. Semble faire les bases avec peu de bruit. Prend en charge les conteneurs imbriqués avec une portée locale des composants et une gestion du temps de vie bien définie.
Voici comment l'initialiser:
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 la meilleure prise en charge des fonctionnalités du langage C # 3.0 et la plus grande flexibilité lors de l'initialisation.
Remarque : Chris Brandsma a transformé sa réponse originale en article de blog .
Pour autant que je l'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 sur la concurrence est qu'il est fourni par Microsoft, il y a beaucoup d'entreprises qui ont peur des logiciels libres.
Un inconvénient est qu'il est plutôt nouveau, il peut donc y avoir des bogues que les joueurs plus âgés ont déjà résolus.
Cela dit, vous voudrez peut-être vérifiez cela .
Vieux 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/
En outre, 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.
Corrigez-moi si je me trompe, mais je pense que Autofac lui-même prend en charge la configuration XML comme indiqué dans ce lien: Configuration XML Autofac
Spring a une fonction qu'il peut 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 de la configuration dans le code.
Windsor peut également le faire, et peut le faire dans du code non config. (corrigez-moi si je me trompe, je passe simplement par ce que j'ai entendu ici).
Je voudrais savoir si Unity peut le faire.
Une chose à noter: Ninject est le seul conteneur IoC qui prend en charge les injections de dépendance contextuelle (selon leur site Web). Cependant, parce que je n'ai pas d'expérience avec d'autres conteneurs IoC, je ne peux pas dire si cela tient.
Juste pour ajouter mes 2 cents, j'ai essayé StructureMap et Unity. J'ai trouvé que StructureMap était mal/mal documenté, une douleur dans le cul à configurer et maladroite à utiliser. De même, il ne semble pas prendre en charge des 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. Alors je l'ai laissé tomber et je suis allé avec Unity, et je l'ai fait faire ce que je voulais en environ 20 minutes.
J'utilise personnellement Unity, mais uniquement parce qu'il provient de Microsoft. Je regrette la décision pour une raison: la plus grande chose contre elle a un gros "bug" qui la fait constamment lever des exceptions. Vous pouvez ignorer les exceptions lors du débogage. Cependant, cela ralentit considérablement votre application si vous la rencontrez, car lever 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:
nity peut-il être fait pour ne pas lancer SynchronizationLockException tout le temps?