Які плюси та мінуси використання 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% випадків (конструкторська ін'єкція, яка в основному використовується людьми МОК). Ви можете переглянути рішення тут (VS2008)
Таким чином, є кілька ключових відмінностей:
Кожен з них також має інші функції (деякі мають AOP і кращі штучки, але я хочу, щоб IOC - це створювати та отримувати для мене об'єкти)
Примітка: відмінності між пошуком об'єктів різних бібліотек можна усунути за допомогою CommonServiceLocator: http://www.codeplex.com/CommonServiceLocator
Це дає нам ініціалізацію, яка робиться двома способами: за допомогою коду або через конфігурацію XML (app.config / web.config / custom.config). Деякі підтримують обоє, деякі підтримують лише одне. Слід зазначити: деякі атрибути використовують, щоб допомогти ІОК.
Тож ось моя оцінка відмінностей:
Ініціалізація коду (лише з атрибутами). Сподіваюся, вам подобаються лямбда. Код ініціалізації виглядає приблизно так:
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, Віндзор зробить все, що ви могли захотіти. Віндзор, мабуть, один з найпопулярніших контейнерів 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 зробити конфігурацію в коді.
Віндзор також може це зробити, і це може зробити в коді не конфігурувати. (виправте мене, якщо я помиляюся, я просто переживаю те, що тут чув).
Я хотів би знати, чи може Єдність це зробити.
Варто зазначити одне: Ninject - єдиний контейнер IoC, який підтримує введення контекстної залежності (відповідно до їх веб-сайту). Однак, оскільки я не маю досвіду роботи з іншими контейнерами IoC, я не можу сказати, чи це справедливо.
Тільки щоб додати свої 2 копійки, я спробував і StructureMap, і Unity. Я виявив, що StructureMap є неякісно / помилково задокументованим, болі в області прикладу для налаштування і незграбний у використанні. Так само, схоже, це не підтримує такі сценарії, як аргумент конструктора переорієнтований на час вирішення, що було для мене ключовим моментом використання. Тож я кинув його і пішов з Unity, і він зробив те, що я хотів, приблизно за 20 хвилин.
Я особисто використовую Unity, але тільки тому, що це від Microsoft. Я шкодую про рішення з однієї причини: найбільше, що він має проти нього, має одну велику "помилку", яка змушує її постійно кидати винятки. Ви можете ігнорувати винятки під час налагодження. Однак це надзвичайно сповільнює вашу програму, якщо ви наштовхуєтесь на неї, оскільки кидати виняток - це дорога операція. Наприклад, зараз я виправляю цей виняток на одному місці свого коду, де виключення Unity додають додаткові 4 секунди до часу візуалізації сторінки. Докладніше та шляхи вирішення див. У розділі:
Чи можна створити Unity, щоб не кидати синхронізаціюLockException весь час?