Какие плюсы и минусы использования Enterprise Library Unity по сравнению с другими контейнерами IoC (Windsor, Spring.Net, Autofac ..)?
@JesonMartajaya, я хотел поблагодарить точно такой же комментарий, досадно, что вопросы закрываются, но нет ответа на альтернативу.





Насколько я видел, они практически одинаковы, за исключением нескольких деталей реализации здесь и там. Самым большим преимуществом Unity перед конкурентами является то, что он предоставляется Microsoft, многие компании опасаются OSS.
Одним из недостатков является то, что он довольно новый, поэтому в нем могут быть ошибки, которые старые игроки уже исправили.
Сказав это, вы можете захотеть Проверь это.
Готовлю презентацию для группы пользователей. Таким образом, я просто прошел через кучу из них. А именно: AutoFac, MEF, Ninject, Spring.Net, StructureMap, Unity и Windsor.
Я хотел продемонстрировать 90% -ный случай (внедрение конструктора, которое в основном используется людьми в любом случае). Вы можете ознакомиться с решением здесь (VS2008)
Таким образом, есть несколько ключевых отличий:
У каждого из них также есть другие функции (у некоторых есть АОП и более совершенные штуковины, но обычно все, что я хочу, чтобы IOC делал, это создавал и извлекал объекты для меня)
Примечание: различия между извлечением объектов из разных библиотек можно свести на нет, используя CommonServiceLocator: http://www.codeplex.com/CommonServiceLocator
Остается инициализация, которая выполняется двумя способами: через код или через конфигурацию XML (app.config / web.config / custom.config). Некоторые поддерживают оба варианта, некоторые - только один. Я должен отметить: некоторые используют атрибуты, чтобы помочь IoC.
Итак, вот моя оценка различий:
Только инициализация кода (с атрибутами). Надеюсь, вам нравятся лямбды. Код инициализации выглядит так:
IKernel kernel = new StandardKernel(
new InlineModule(
x => x.Bind<ICustomerRepository>().To<CustomerRepository>(),
x => x.Bind<ICustomerService>().To<CustomerService>(),
x => x.Bind<Form1>().ToSelf()
));
Код инициализации, XML или атрибуты. v2.5 тоже очень лямбдай. В общем, это один из моих любимых. Несколько очень интересных идей о том, как StructureMap использует атрибуты.
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>();
});
Код инициализации и XML. Хорошая библиотека, но конфигурация XML - это головная боль. Отличная библиотека для Microsoft или уличных магазинов. Инициализация кода проста:
container.RegisterType<ICustomerRepository, CustomerRepository>()
.RegisterType<ICustomerService, CustomerService>();
XML только насколько я могу судить. Но для функциональности Spring.Net делает все, что может делать IoC. Но поскольку единственный способ объединения в единицы - это XML, его обычно избегают магазины .net. Хотя многие магазины .net / Java используют Spring.Net из-за схожести между .net-версией Spring.Net и проектом Java Spring.
Примечание: Конфигурация в коде теперь возможна с введением Spring.NET CodeConfig.
XML и код. Как и Spring.Net, Windsor сделает все, что вы захотите. Windsor, вероятно, является одним из самых популярных контейнеров IoC.
IWindsorContainer container = new WindsorContainer();
container.AddComponentWithLifestyle<ICustomerRepository, CustomerRepository>("CustomerRepository", LifestyleType.Singleton);
container.AddComponentWithLifestyle<ICustomerService, CustomerService>("CustomerService",LifestyleType.Singleton);
container.AddComponent<Form1>("Form1");
Может смешивать как XML, так и код (с v1.2). Хорошая простая библиотека IoC. Кажется, делает основы без особой суеты. Поддерживает вложенные контейнеры с локальной областью действия компонентов и четко определенным управлением сроком службы.
Вот как вы его инициализируете:
var builder = new ContainerBuilder();
builder.Register<CustomerRepository>()
.As<ICustomerRepository>()
.ContainerScoped();
builder.Register<CustomerService>()
.As<ICustomerService>()
.ContainerScoped();
builder.Register<Form1>();
Если бы мне пришлось выбирать сегодня: я бы, наверное, выбрал StructureMap. Он имеет лучшую поддержку функций языка C# 3.0 и максимальную гибкость при инициализации.
Примечание: Крис Брандсма превратил свой исходный ответ в Сообщение блога.
Только конфигурация XML, что значительно усложняет настройку. По сути, единственные люди, которые, как я вижу, хотят использовать Spring.Net, - это бывшие разработчики Java.
Крис, что касается ваших выводов: не могли бы вы подробнее рассказать а) о каких функциях C# 3 вы имеете в виду и б) какие виды инициализации важны для вас? Спасибо!
Привет, Николас: что касается поддержки C# 3, все, что уже делает Autofac. :) Для инициализации мне нужна простая поддержка синглтонов / не синглтонов и инициализация для каждой сессии. Наконец, мне нужны простые способы ссылки по собственному имени. (то, что является PITA в StructureMap). Последняя функция, которая мне нравится больше, чем когда я писал ее изначально: AutoMocking. Я не использую его постоянно, но это очень приятно.
Вы также упомянули MEF, я использую MEF для доставки своих объектов реализации IRepository и считаю, что он отлично работает. Что ты думаешь о MEF?
Вот хороший 20-минутный скринкаст, демонстрирующий большую часть Unity: pnpguidance.net/Screencast/…
Ребята из Spring.NET работали над конфигурацией кода. Не знаю где это, но заинтересованные могут пройти по этой ссылке eeichinger.blogspot.com/2009/12/…
Unity поддерживает конфигурацию как XML, так и кода. Это очень зрелый и гибкий контейнер.
Доступна конфигурация @Chris Code для Spring. springframework.net/codeconfig
Прежде всего - отличный ответ, Крис. Одна вещь, которую я хотел бы упомянуть, - это проблема круговой зависимости. Насколько мне известно, Unity выдает только StackOverflowException, в то время как другие контейнеры IoC более выразительно информируют о причине проблемы (см. stackoverflow.com/questions/37571899/…). Для меня это существенный недостаток Unity.
Поправьте меня, если я ошибаюсь, но я думаю, что Autofac сам поддерживает конфигурацию XML, как указано в этой ссылке: Конфигурация Autofac XML
Spring имеет одну особенность: он может вводить параметры в конструктор или свойство в зависимости от имени или позиции параметра. Это очень полезно, если параметр или свойство имеет простой тип (например, целое число, логическое значение). См. пример здесь. Я не думаю, что это действительно компенсирует неспособность Spring выполнить конфигурирование в коде.
Виндзор также может это делать, и может делать это в коде, а не в конфигурации. (поправьте меня, если я ошибаюсь, я просто прохожу через то, что слышал здесь).
Я хотел бы знать, может ли Unity это сделать.
Следует отметить одно: Ninject - единственный контейнер IoC, который поддерживает внедрение контекстных зависимостей (согласно их веб-сайту). Однако, поскольку у меня нет опыта работы с другими контейнерами IoC, я не могу сказать, так ли это.
Если это все "контекстная инъекция зависимостей" в Ninject, то .. эээ, ничего особенного. Поддерживается (различными способами) как минимум в Unity, AutoFac, Windsor.
Старая ветка, но так как это первое, что показал мне Google, когда я набрал unity vs spring.net ...
Spring делает CodeConfig сейчас, если вам не нравится конфигурация XML
http://www.springframework.net/codeconfig/doc-latest/reference/html/
Кроме того, Spring - это намного больше, чем просто контейнер DI. Если вы посмотрите на раздел «Модули» в документации, контейнер DI - это основа огромного набора функций, которые он выполняет.
Чтобы добавить свои 2 цента, я пробовал и StructureMap, и Unity. Я обнаружил, что StructureMap плохо / неправильно задокументирована, неудобна для настройки и неудобна в использовании. Точно так же, похоже, он не поддерживает такие сценарии, как переопределение аргументов конструктора во время разрешения, что было для меня ключевым моментом использования. Так что я бросил его и пошел с Unity, и он сделал то, что я хотел, примерно за 20 минут.
Я лично использую Unity, но только потому, что он от Microsoft. Я сожалею о своем решении по одной причине: самая большая вещь, которую он имеет против него, - это одна большая «ошибка», которая заставляет его постоянно генерировать исключения. Вы можете игнорировать исключения во время отладки. Однако это замедляет работу вашего приложения чрезвычайно, если вы столкнетесь с ним, поскольку создание исключения - дорогостоящая операция. Например, в настоящее время я «исправляю» это исключение в одном месте моего кода, где исключения Unity добавляют дополнительный 4 секунды ко времени рендеринга страницы. Дополнительные сведения и обходной путь см. В следующих разделах:
Можно ли заставить Unity не генерировать SynchronizationLockException все время?
Спасибо за предупреждение! Согласно этот ответ из вопроса, который вы упомянули, ошибка устранена.
Извините, эта "ошибка" решена или вы нашли способ ее избежать? Я выбираю фреймворк в C# .net сейчас и хочу знать, является ли единство временными затратами ...
Такие вопросы всегда закрыты. Мнения важны. Есть где их разместить?