пятница, 17 декабря 2010 г.

Autofac extensions for PRISM 4

PRISM
Prism это набор практик , для более простого проектирование богатых, гибких и легких в обслуживании Windows Presentation Foundation (WPF), десктоп приложений, Silverlight Rich Internet Applications (RIA), и Windows 7 Phone приложений. Использование паттернов, воплощают важные архитектурные принципы дизайна, такие как разделение ответственности и слабую связь. Prism позволяет проектировать и строить приложения с использованием слабо связанных компонентов, которые могут развиваться самостоятельно, но которые могут быть легко интегрированы. Такой тип приложений известен как «Модульные приложения».
Последняя версия Prism направленна на Microsoft. NET Framework 4.0 и Silverlight 4 и включает в себя новый принцип реализации модели Model-View-ViewModel (MVVM) паттерна, навигации и Managed Extensibility Framework (MEF).

Подробно.

Autofac
Autofac это IoC контейнер для Microsoft .NET. Он управляет зависимостями между классами таким образом, чтобы приложения оставалось легко изменяемым по мере роста  размера и сложности. Это достигается путем обработки обычных классов в виде компонентов.
Последняя версия (2.3) распространяется в виде одной dll’ки размером около 100KB.
Подробно.

Enable Autofac in PRISM
Контейнер Инъекции Зависимостей (Dependency injection containers), дальше просто "контейнер" используются для удовлетворения зависимостей между компонентами; удовлетворение таких зависимостей, как правило, предполагает регистрацию и разрешение компонентов. Из коробки призм обеспечивает поддержку Unity контейнер и Mef, но он является независимым от конкретной реализации контейнера. Поскольку библиотека получает доступ к контейнеру через интерфейс IServiceLocator, он может быть заменен. Для этого, ваш контейнер должен реализовать  интерфейс IServiceLocator. Обычно, если вы заменяете контейнер, вы должны также предоставить собственный загрузчик приложения (Bootstrapper) который зависит от реализации контейнера. Какой контейнер использовать – дело личных предпочтений. Я предпочитаю использовать Autofac, поэтому для того чтобы связать его и Prism, необходимо написать собственную реализацию Bootstrapper и IServiceLocator.
Prism очень гибок и расширяем, что позволяет его «заточить» под решение конкретной задачи. При этом архитектура приложения будет «правильной», т.е. готова к изменениям на любом уровне и без последствий (ну или с минимальными). Что еще не маловажно, Prism помогает писать тестируемые приложения с помощью UnitTest’ов.

AutofacBootstrapper
AutofacBootstrapper – реализация абстрактного класса Bootstrapper. Данный класс обеспечивает последовательность начальной загрузки приложения, и регистрирует необходимые компоненты в контейнере Autofac. Реализация ключевых методов класса AutofacBootstrapper выглядит сл. образом:
 
 public abstract class AutofacBootstrapper : Bootstrapper
 {
  
  protected virtual IContainer CreateContainer()
  {
   return ConfigureContainer().Build();
  }

  protected virtual ContainerBuilder ConfigureContainer()
  {
    var containerBuilder = new ContainerBuilder();

    containerBuilder.RegisterInstance(Logger);
    containerBuilder.RegisterInstance(ModuleCatalog);
    containerBuilder.RegisterSource(new ResolveAnythingRegistrationSource());

    if (_useDefaultConfiguration)
    {
      containerBuilder.Register(x => new AutofacServiceLocatorAdapter(Container))
      .As<IServiceLocator>().SingleInstance();
   
      containerBuilder.RegisterType<ModuleInitializer>()
      .As<IModuleInitializer>().SingleInstance();
   
      containerBuilder.RegisterType<ModuleManager>().
      As<IModuleManager>().SingleInstance();
   
      containerBuilder.RegisterType<EventAggregator>()
      .As<IEventAggregator>().SingleInstance();

      containerBuilder.RegisterModule(new RegionInitializerModule());
      containerBuilder.RegisterModule(new RegionAdapterInitializerModule());
    }

    return containerBuilder;
  }

  public override void Run(bool runWithDefaultConfiguration)
  {
   //run workflow
  }
 }

Метод “ConfigureContainer” конфигурирует контейнер и возвращает объект, «ContainerBuilder» который, после операции “Build” превратится в рабочий контейнер. В обязательном порядке, контейнер регистрируются “Logger” и “ModuleCatalog”. В контейнер они регистрируются как созданные и сконфигурированные объекты, потому при инъекциях, не будут создаваться новые, а будут использоваться те, что использовались при регистрации. Если приложение использует конфигурацию по умолчанию, в контейнер регистрируются следующие компоненты:
•    AutofacServiceLocatorAdapter - адаптер контейнера, для абстракции от конкретной реализации контейнера
•    ModuleInitializer – компонент, который создает экземпляр загружаемого модуля и инициализирует его.
•    ModuleManager – компонент, который производит загрузку удаленного модуля и зависимостей. После загрузки, модуль инициализируется при помощи компонента “ModuleInitializer”.
•    EventAggregator – компонент, который реализует одноименный паттерн.
•    RegionInitializerModule – класс, который производит настройку компонентов для работы с регионами.

Также в контейнер регистрируется компонент “ResolveAnythingRegistrationSource”, который расширяет возможности Autofac способностью создавать типы не зарегистрированые в нем непосредственно. Это необходимо для создания экземпляров модулей, которые описаны с помощью структуры «ModuleInfo», которая обеспечивает позднее связывание.
Это метод необходимо перегрузить для регистрации собственных компонентов. Ниже представлен пример из кода “Quickstarts- Modularity”:
protected override ContainerBuilder ConfigureContainer()
{
 var containerBuilder = base.ConfigureContainer();

 containerBuilder.RegisterType()
                 .As().SingleInstance();
 containerBuilder.RegisterInstance(callbackLogger);
 containerBuilder.RegisterType();

 return containerBuilder;
}
Метод «CreateContainer» создает контейнер из сконфигурированного «СontainerBuilder». Практическт во всех случаях его не нужно переопределять.

Метод «Run» запускает процесс инициализации приложения в строго определенной последовательности.


Последовательность инициализиции компонентов

 
Данную последовательность необходимо придерживать при реализации собственного метода.
Параметр, передаваемый в метод, регулирует процесс инициализиции. Если  метод был вызван с параметром «True», то нициализация пройдет в обычном режиме и будут проинициализированы и зарегистрированы все необходимые компоненты. Иначе, класс наследник обязывается провести инициализацию этих компонентов самостоятельно. В большинстве случаев нет необходимости менять логику работы этого метода.

AutofacServiceLocatorAdapter
Определяет адаптер для интерфейса IServiceLocator, которые будут использоваться Composite Application библиотеки. Интерфейс IServiceLocator находится  в  Common Service Locator библиотеке. Эта библиотека с открытым исходным кодом, предназначена для того, чтобы обеспечить абстракцию от IoC (Inversion of Control) контейнера, и сервис локатора (service locator). Цель использования этой библиотеки заключается в привлечении IoC и Service Location без привязки к конкретной реализации. Prism не ссылается или полагаться на конкретный контейнер, но приложение может полагаться на конкретный контейнер. Это означает, что целесообразно для конкретного приложения ссылаться на контейнер, но Prism этого не делает непосредственно.

RegionInitializerModule
Данный модуль использоваться для расслоения на множество связанных с ним компонентов для упрощения настройки и развертывания. Модуль предоставляет преднамеренно ограниченный набор конфигурационных параметров, которые могут изменяться независимо от компонентов, используемых для реализации модуля.

ResolveAnythingRegistrationSource
Данное расширание к Autofac позволяет решить проблему инстенцирования компонентов,  которые не были зарегистрированиы в контейнер во время инициализации приложения. Это нужно в момент загрузки и инициализации распределенных модулей приложения. Необходимо отметить, что его использование для инстенцеирование заранее известных компонентов не рекомендуется, так как скорость поиска объектов в контейнере снижается.

Source code

0 коммент.:

Отправить комментарий

Newer Posts Older Posts