Первый взгляд на Unity 2.0

Автор оригинала: Dino Esposito
  • Перевод
image
Unity – это проект с открытым исходным кодом от группы Patterns & Practices в Microsoft. Цель проекта – предоставить классический IoC фреймворк для разработчиков, позволяющий инстанцировать объекты продвинутым образом и иметь возможность гибкой конфигурации. Unity представляет собой отдельный фреймворк, но часто включается в проекты как часть Enterprise Library. С приходом .NET 4 и Visual Studio 2010, на подходе и новые версии Unity и Enterprise Library. В этой статье рассматривается бета-версия Unity 2.0. Чтобы попробовать фреймворк самим, посетите http://unity.codeplex.com. Релиз Unity 2.0 и Enterprise Library 5.0 намечен на тоже время, что и релизы Visual Studio 2010 и .NET 4, то есть этой весной.

Несколько фактов о Unity 2.0


Когда новый релиз продукта выходит, первый вопрос, который возникает: могу ли я запросто обновить свои старые бинарные компоненты с новыми и быть счастливым? Второй частый вопрос: могу ли я использовать старую версию продукта совместно с новой версией? Для Unity 2.0 ответ на оба вопроса: ДА. Вы легко можете мигрировать имеющиеся приложения на новую версию инструмента и вы так же можете использовать версии 1.2 и 2.0 совместно в контексте одного приложения. Тем не менее, в случае совместного использования вам необходимо проделать несколько действий, чтобы убедиться, например, в том что сборки Unity расположены в разных папках (так как они имеют одно и тоже имя) и каждая ваша сборка зависит только от одной из версий Unity.

Говоря о сборках, нужно заметить, что вся функциональность Unity 2.0 представлена тремя сборками:
  • Microsoft.Practices.Unity
  • Microsoft.Practices.Unity.Configuration
  • Microsoft.Practices.Unity.Interception
Первая содержит ядро библиотеки, остальные две сфокусированы на специфических аспектах, таких как поддержка офлайн-конфигурирования через XML и реализация паттерна Перехват (Interception). Основное отличие с предыдущей версией Unity в отсутствии сборки ObjectBuilder2, код которой отныне включен в ядро Microsoft.Practices.Unity.

В зависимости от того, с какой целью вы использовали Unity 1.2 и какие функции внедряли, вы можете столкнуться, а можете и не столкнуться с трудностями миграции вашего существующего кода на новую версию. На первый взгляд, по моим ощущениям, миграция в большинстве случаев проходит плавно и без проблем, но некоторые изменения все же имеются и кое-какой старый код может оказаться устаревшим в свете новой версии Unity.

Определение зависимостей с Unity 2.0


Так как основная цель Unity – это разрешение зависимостей между классами, первоочередная задача состоит в том, как выразить эти зависимости. Есть два пути: использование офлайн-файла конфигурации и выражение зависимостей через гибкий API во время исполнения.

По умолчанию, Unity считывает конфигурационные параметры из XML-файла, чаще всего это файлы конфигурации приложения вроде app.config или web.config. Но вы не ограничены в своем выборе и можете загружать параметры конфигурации из любого XML-файла, который был включен в ваш проект. Например, у вас есть файл my.config с настройками конфигурации Unity. Следующий код показывает, как вы можете загрузить из него информацию в текущий экземпляр контейнера:

image

Этот код слегка отличается от того, что вы могли использовать в версии 1.2. Старый код отныне помечен как устаревший. Основное отличие в строке кода, которая загружает информацию о конфигурации в контейнер. Теперь у вас есть новый метод Configure у объекта section.

Имейте в виду, что если вы используете конфигурационный файл не по умолчанию, то вам необходимо убедиться в том, что .config-файл размещен в одной папке с исполняемым файлом. Ниже представлен код, который загружает конфигурацию из файла по умолчанию:

image

Конечный код, безусловно, чище, чем код написанный в прошлых версиях. Кроме того, есть еще более приятные новости для Unity-разработчиков: в комплект Unity 2.0 входит очень приятный конфигурационный инструмент, с помощью которого вы можете “выразить и объявить” ваши зависимости.


Рис. 1. Секция Unity, настраиваемая с помощью утилиты конфигурации Enterprise Library

Этот инструмент может сохранять настройки в любой файл, а так же может комбинировать вместе секции из Enterprise Library и Unity. Инструмент так же открывает файлы, которые вы могли создать в Visual Studio либо где-то еще.

Офлайн-конфигурирование – это прекрасная вещь, но она является декларативным API. Есть множество ситуаций, когда вам нужно больше гибкости и, конечно, ситуации в которых вы выбираете подходы, которые предлагают большую гибкость. Альтернативой офлайн-конфигурации на этапе дизайна является конфигурирование во время исполнения.

image

Класс UnityContainer поддерживает гибкий синтаксис, который позволяет вам разбивать на цепочки комбинации методов класса для достижения желаемой конфигурации. Например, вы можете использовать RegisterType для регистрации мэппинга типов и RegisterInstance для регистрации экземпляра определенного типа. Вы так же можете комбинировать вызов с AddExtension чтобы использовать interception API Unity. Кроме того, класс UnityContainer содержит новый метод расширения IsRegistered, который позволяет вам проверить указанный тип на то, был ли он уже зарегистрирован с помощью фреймворка.

image

Этот метод – одна из функций добавленных в Unity 2.0 и полезная в сценариях, когда вы предполагаете интегрировать вместе конфигурации во время дизайна и во время исполнения. Вы можете использовать этот метод для того, чтобы избежать множественных одинаковых регистраций, которые будут автоматически разрешаться с использованием последнего добавленного правила. В Unity 2.0 вы так же обнаружите для себя новую коллекцию Registrations, предназначенную для программной проверки наличия регистраций на момент исполнения. Registrations возвращает коллекцию объектов типа ContainerRegistration, который описан ниже:

image

Как вы можете видеть, объект ContainerRegistration представляет собой точное описание регистрации вне зависимости от того, как она была создана: через XML или программно.

Разрешение зависимостей с помощью Unity 2.0


Unity 2.0 по-прежнему содержит метод Resolve с тем же синтаксисом, который знаком вам по предыдущим версиям. После того, как контейнер был сконфигурирован каким-либо способом, все что нам нужно – это построить экземпляры спроецированных типов. Для этой цели служат методы Resolve и Resolve<T>:
image

Метод разрешения проделывают всю магию по определению структуры целевого типа и поиску его зависимостей, для их разрешения. Как и многие другие IoC-фреймворки, Unity поддерживает зависимости указанные через конструктор и атрибуты внедрения (injection attributes), которые могут быть указаны для свойств или методов. Экземпляр, который возвращает Resolve или Resolve<T> содержит в себе все имеющиеся зависимости разрешенными, в случае, когда зависимость не была разрешена, фреймворк выкидывает исключение.

Unity может также разрешать дженерик-типы, как связанные, так и несвязанные. Ниже представлена регистрация несвязанного дженерик-типа (в котором, тип T неизвестен):

image

Тип ISpecialLogger<T> проецируется на закрытый тип, которому известно только то, как обрабатывать целые значения. Ниже, для примера, описание такого типа:

image

В своем коде вы просите Unity разрешить ISpecialLogger<int> и получить объект, который знает как логировать целые значения:

image

Кольцевые ссылки – это серьезная опасность при использовании Unity и в целом контейнеров IoC. Кольцевые зависимости трудно выявить и они должны рассматриваться как знак плохого дизайна приложения, а не как случайный результат из-за отсутствия функционала в вашем IoC. Когда класс предоставляет несколько конструкторов, Unity по умолчанию использует один с самым большим числом параметров. Порой, это может привести к появлению кольцевых ссылок, который никогда бы не появились, когда вы создаете классы вручную. Например, у нас есть два класса:

image

Все в порядке, пока вы самостоятельно инстанцируете экземпляры класса:

image

Если вы поручите Unity разрешить класс, то получите переполнение стека:

image

Причина исключения с переполнением стека состоит в том, что Unity, используя конструктор с самым большим числом параметров попадает в кольцевые ссылки, когда пытается получить экземпляр MyService чтобы разрешить MyContainer, который в свою очередь требуется для разрешения MyService.

В завершении, стоит описать, что Unity 2.0 содержит несколько новых менеджеров жизненного цикла (lifetime managers). В предыдущей версии у нас было три предопределенных менеджера, плюс возможность создавать свои. В таблице 1 описаны менеджеры доступные в Unity 2.0.

Таблица 1. Менеджеры жизненного цикла в Unity 2.0
Менеджер
Описание
ContainerControlledLifetimeManager
Реализует поведение singleton для объектов. Объект разрушается (disposed), когда разрушается контейнер.
ExternallyControlledLifetimeManager
Реализует поведение singleton, но контейнер не хранит ссылку на объект, так что объект разрушается после выхода из области видимости.
HierarchicalifetimeManager
Новое в Unity 2.0, реализует поведение singleton для объектов. Но, контейнеры-потомки не разделяют экземпляры с родителями.
PerResolveLifetimeManager
Новое в 2.0, реализует поведение похожее на transient lifetime manager, за исключением того, что экземпляры повторно используются в построении графа объектов (instances are reused across build-ups of the object graph).
PerThreadLifetimeManager
Реализует поведение singleton для объектов, но ограничивает их текущим потоком.
TransientLifetimeManager
Возвращает новый экземпляр запрошенного типа при каждом вызове. Это поведение по умолчанию.
Как и ожидалось, разрешение по умолчанию в Unity возвращает новый экземпляр на каждый вызов. То же самое было и в предыдущих версиях.

Заключение


На момент написания этой статьи, фреймворк Unity 2.0 оставался в статусе бета-версии. В этой версии нет ничего революционного. Тем не менее, исправлена конфигурация – область в которой фреймворк уступал другим блокам из Enterprise Library в обоих видах: при дизайне и API. И другое важное изменение: теперь, если вы хотите использовать только чистое внедрение кода, вам нужна всего одна DLL.

Финальный релиз ожидается в апреле, сразу же за релизом Visual Studio 2010 и .NET Framework 4. Тем не менее, Unity 2.0 не специфична для .NET 4 и может быть использована так же и дла .NET 3.5.

Progg it

Похожие публикации

AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 17

    –7
    Ну почему… почему крупные корпорации не пользуются поиском прежде чем выдвинуть очередное «шикарное» и «новое» имя для какой-нибудь технологии. unity3d.com
      0
      Они пользуются ;)
        0
        Полное название DI/IoC-контейнера — Unity Application Block
          0
          А какая связь? Вы что-то напутали…
            +1
            Связь в том, что когда говорят, например «проект нужно будет писать используя Unity» — ты точно не знаешь о чем речь. А искать как хелпы под одному из трех «Unity» — каша одинаково названных проектов не помогает…

            К моменту выхода «Unity» от Microsoft — «Unity» от Unity Technologies существовал уже три года.
            Я уж молчу, что в 88 году был сделан язык Unity.

            Минусуйте дальше сколько влезет, товарищи фанаты MS. Сейчас это может не казаться проблемой, но если так продолжат, через 10 лет будет под десяток видов «Unity» (3 значения в IT сейчас), «Go» (2 значения в IT сейчас) и «Closure» (3 значения в IT сейчас) и будете наслжадаться поиском документации среди груды мусора по темам, который не имеет к Вашему проекту никакого отношения.
              +1
              why so serious?
            0
            Им банально пофиг.
            0
            Только мне показалось что не мешало бы сначала хоть ссылку дать на материал о том что такою Unity и какова идеология?
              +1
              вы не поверите, в первом же абзаце есть ссылка
              +1
              Спасибо за очень полезную статью. Считаю, что Enterprise Library — это одна из самых полезных библиотек для .NET разработчика, которая экономит кучу времени и сил. Порадовало, что Unity получит UI для редактирования конфига, этого очень не хватало.
                0
                ИМХО, entlib полезен как раз в плане Unity как понятного фреймворка. Что касается других аспектов, то это на любителя — например для логирования как-то привычней log4net.
                  0
                  Опять же ИМХО, в EL меня подкупает удобные мастера, которые позволяют быстро конфигурировать нужные модули. Согласен, что привычка иногда решает
                0
                А можно в двух словах по-русски? В чем проблема, что такое Unity и как оно решает эту проблему.

                Спасибо заранее.
                  +1
                  Программист — это человек, который может решить неизвестную вам задачу, способом который вы не поймете)
                    0
                    Решает проблему жесткости дизайна кода.

                    Жесткость дизайна – это его сопротивление к изменениям. Изменение в одном модуле системы, влечет за собой необходимость внесения каскадных изменений в другие модули. Как правило, в такой ситуации, разработчик постоянно ошибается при оценке времени необходимого для выполнения той или иной задачи по сопровождению системы.

                    Чтобы решить эту проблему был придуман принцип:
                    Модули верхнего уровня не должны зависеть от модулей нижнего уровня.

                    И вот для того чтобы красиво реализовать этот принцип придумываются различные Dependency Inversion библиотеки (Unity в данном случае).
                    0
                    www.ibm.com/developerworks/ru/library/j-ioc/index.html — вот тут есть немного, для тех кто не в курсе
                      +1
                      Прошу прощения, вот еще уже в Хабре — habrahabr.ru/blogs/net/62830/

                      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                      Самое читаемое