Каковы преимущества и недостатки использования Enterprise Library Unity по сравнению с другими контейнерами IoC (Windsor, Spring.Net, Autofac ...)?
Каковы преимущества и недостатки использования Enterprise Library Unity по сравнению с другими контейнерами IoC (Windsor, Spring.Net, Autofac ...)?
Ответы:
Я готовлю презентацию для группы пользователей. Таким образом, я только что прошел через них. А именно: AutoFac, MEF, Ninject, Spring.Net, StructureMap, Unity и Windsor.
Я хотел похвастаться 90% случая (инжектор конструктора, который в основном то, для чего люди все равно используют IOC). Вы можете проверить решение здесь (VS2008)
Таким образом, есть несколько ключевых отличий:
У каждого из них есть и другие функции (у некоторых есть AOP и лучшие вещицы, но, как правило, все, что я хочу, чтобы 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 shop используют Spring.Net из-за сходства .net-версии Spring.Net и проекта Java Spring.
Примечание : настройка в коде теперь возможна с введением Spring.NET CodeConfig .
XML и код. Как Spring.Net, Виндзор сделает все, что вы захотите. Виндзор, вероятно, один из самых популярных контейнеров 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 и большую гибкость при инициализации.
Примечание : Крис Брандсма превратил свой оригинальный ответ в сообщение в блоге .
Насколько я видел, они практически одинаковы, за исключением нескольких деталей реализации здесь и там. Самое большое преимущество, которое Unity имеет перед конкурентами, заключается в том, что он предоставляется Microsoft, и многие компании боятся OSS.
Недостатком является то, что он довольно новый, поэтому в нем могут быть ошибки, которые старые игроки уже разобрали.
Сказав это, вы можете проверить это .
Старая ветка, но так как это первое, что Google показал мне, когда я набрал текст в единстве против spring.net ...
Spring делает CodeConfig сейчас, если вам не нравится конфигурация XML
http://www.springframework.net/codeconfig/doc-latest/reference/html/
Кроме того, Spring - это гораздо больше, чем просто контейнер DI. Если вы посмотрите на раздел «Модули» в документации, контейнер DI является основой огромного стека вещей, которые он делает.
Поправьте меня, если я ошибаюсь, но я думаю, что Autofac сам поддерживает XML-конфигурацию, как указано в этой ссылке: Autofac XML Configuration
Spring имеет одну особенность: он может вводить параметры в конструктор или свойство на основе имени или позиции параметра. Это очень полезно, если параметр или свойство имеют простой тип (например, целое число, логическое значение). Смотрите пример здесь . Я не думаю, что это действительно компенсирует неспособность Spring конфигурировать код.
Виндзор также может сделать это, и может сделать это в коде не конфигурации. (поправьте меня, если я ошибаюсь, я просто через то, что я услышал здесь).
Я хотел бы знать, может ли Unity сделать это.
Стоит отметить одну вещь: Ninject - единственный контейнер IoC, который поддерживает контекстные инъекции зависимостей (согласно их веб-сайту). Однако, поскольку у меня нет опыта работы с другими контейнерами IoC, я не могу сказать, так ли это.
Просто чтобы добавить свои 2 цента, я попробовал и StructureMap, и Unity. Я обнаружил, что StructureMap плохо / неверно задокументирован, это проблема в настройке и неудобная работа. Точно так же он не поддерживает сценарии, такие как переопределение аргументов конструктора во время разрешения, что было для меня ключевым моментом использования. Поэтому я бросил его и пошел с Unity, и он делал то, что хотел, примерно через 20 минут.
Я лично использую Unity, но только потому, что он от Microsoft. Я сожалею о решении по одной причине: самая большая вещь, которую он имеет против этого, имеет одну большую "ошибку", которая заставляет его постоянно генерировать исключения. Вы можете игнорировать исключения во время отладки. Однако это замедляет ваше приложение чрезвычайно если запустить через него, так как бросать исключение является дорогостоящей операцией. Например, в настоящее время я «исправляю» это исключение в одном месте моего кода, где исключения Unity добавляют дополнительные 4 секунды ко времени отображения страницы. Для получения дополнительной информации и обходного пути см .:
Можно ли заставить Unity не генерировать SynchronizationLockException все время?