Продолжаем знакомство с
серией статей об IoC
контейнерах
для управления зависимостями. На этот раз “жертвой” критики станет IoC контейнер
Spring.Net. Предыдущие статьи были посвящены
таким IoC
контейнерам,
как Unity, Autofac, CastleWindsor
и StructureMap.
Spring.Net -
это портированный с языка Java
IoC
контейнер.
По отношению к анализируемому IoC
контейнеру
было упомянуто слово “жертва”, что вписывается в данный контекст его описания,
поэтому сразу предупреждаю об этом поклонников Spring.Net перед ознакомлением с данным
материалом. На момент написания статьи была доступна версия 1.3.2, и за два года
с момента использования этого контейнера в последний раз не произошло
существенных изменений. Приведу интересную схему, описывающую работу
контейнера, взятую с официального сайта, посвященного Spring.Net.
Как видите, судя по
рисунку, все довольно просто: достаточно сконфигурировать в xml файле
-
и можно просто использовать. Ниже приведена диаграмма классов для демонстрации
работы данного IoC
контейнера.
Для примера использовалась связка WPF + MVVM.
Основная модель
представления представлена классом MainViewModel. С помощью этой модели и будет продемонстрирована
вся мощность Spring.Net. Рассмотрим, как будет реализован
самый простой сценарий constructor
injection
(CI) для класса MainViewModel, чтобы посмотреть на Spring.Net в
действии. Чтобы инициализировать IoC
контейнер
перед стартом программы, необходимо перейти в классыApp.xaml.cs и
переопределить метод OnStartup.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="spring">
<section name="objects" type="Spring.Context.Support.DefaultSectionHandler,
Spring.Core" />
</sectionGroup>
</configSections>
<spring>
<objects xmlns="http://www.springframework.net">
<object id="LibraryBook" type="SpringDemo.Model.LibraryBook,
SpringDemo"/>
<object id="LibraryBookService" type="SpringDemo.Model.LibraryBookService,
SpringDemo"/>
<object id="MainViewModel" type="SpringDemo.ViewModel.MainViewModel,
SpringDemo">
<constructor-arg ref="LibraryBookService" />
</object>
</objects>
</spring>
</configuration>
Пример файла конфигурации для настройки IoC контейнера Spring.Net с реализацией:
using (var container = new XmlApplicationContext("config://spring/objects"))
{
var model =
container.GetObject("MainViewModel");
var view = new MainWindow { DataContext = model };
view.Show();
}
Как видим из примера,
использовать Spring.Net несложно. Многие разработчики
могут сказать, что же в этом подходе не так. Пожалуй, отвечу на этот вопрос
более обширно. Данный подход наверняка очень понравится любителям NHibernate, так как они привыкли
использовать xml
для
конфигурирования связей с БД. Теперь пройдусь по негативным (по субъективной
оценке) моментам касательно Spring.Net, основным из которых является полное
отсутствие конфигурирования и настройки данного IoC контейнера,
кроме xml.
Получить нужную реализацию
можно с помощью метода GetObject. Этот метод возвращает тип Object. Мне действительно
не понятно, почему нельзя было сделать хотя бы extension методы, чтобы не приводить явно к нужной
реализации. Хотя здесь я переборщил, так как уже вышла пререлиз-версия 2.0, в которую наконец добавили GetObject<T>, который позволяет возвращать сразу новый тип. Многие могут возразить,
что не проблема привести с Object к нужному типу. Соглашусь, это не
проблема, но зачем это делать, если есть множество IoC контейнеров, которые позволяют делать то же самое без лишних усилий с вашей стороны.
При установке с помощью NuGet Packages данный IoC контейнер грузит поддержку для всех
типов .Net Framework. Это выглядит так:
Спрашивается,
зачем нужно тащить, указав в сборке проекта 4 фреймворк, 35 Мб библиотеки, которые мне, по сути, не нужны.
Почему-то проект с
использованием Spring.Net долго
собирается. Единственный IoC
контейнер, который почему-то инициализируется так же долго - это CastleWindsor. Но он в несколько раз
превосходит по возможностям данный контейнер, так что это можно отнести в раздел
маленьких неудобств.
Разработчики данного IoC контейнера
заявляют о поддержке аспектного программирования (interception), что является
достоинством данного контейнера. Но какие популярные контейнеры не имеют такой
особенности? На момент написания статьи такую возможность имеют StructureMap, CastleWindsor, Unity и
Autofac.
Итоги
В данной статье был
приведен краткий обзор IoC
контейнера
Spring.Net. Материал по отношению к данному контейнеру имеет характер критики. С моей точки зрения, этот контейнер
уступает всем популярным контейнерам. Надеюсь, после ознакомления с материалом Вы обратите внимание на другие IoC
контейнеры, часть из которых описана в предыдущих статьях, и выберете наиболее целесообразно подходящий.
Источники:
No comments:
Post a Comment