Szukaj na tym blogu

wtorek, 23 listopada 2010

Przegląd PRISM 4 – część 1

Tematem części 1 będzie, krótki opis na temat tego czym jest Prism, oraz opis Boostrapera.

Co to jest Prism ?
Prism to framework zawierająy szereg narzędzi ułatwiających budowę aplikacji składających się z niezależnych modułów. Wbrew pozorom, tak jak wiele osób uważa, Prism nie jest kolejnym frameworkiem MVVM. Wiele z ficzerów (Unity, EventAggregator) wchodzących w skład Prisma jest wykorzystywanych we własnych implementacjach MVVM typu Cinch, Caliburn etc.

Dlaczego warto korzystać z Prism’a ?
Głównie po to by móc tworzyć niezależne od siebie moduły tzn. zespoły programistów skupiają się na tworzeniu tylko danego kawałka funkcjonalności całego projektu (może to być część biznesowa jak również techniczna- infrastrukturalna). Zabieg ten wprowadza łatwiejsze testowanie poszczególnych modułów, zarządzanie całym projektem czy też aktualizacje danych funkcjonalności. W środowisku Silverlight modułowość pozwala także na przesłanie do klienta tylko tych modułów, których aktualnie potrzebuje przez co transfer danych pomiędzy serwerem, a klientem jest mniejszy (= działa szybciej).

Co nowego w wersji 4 ?
- wsparcie dla MEF (Managed Extensibility Framework) – MEF pełni rolę kontenera DI oraz zarządzania modułami,
- wsparcie dla MVVM - o tym szerzej w kolejnych częściach,
- wsparcie dla nawigacji .
Poza dodatkowymi funkcjonalnościami w wersji czwartej, zmianom uległa licencja, namespace etc.

Założenia
Z racji osobistych powódek, założyłem, że wykorzystam:
- Unity jako kontener UI,
- modułowość,
- nawigację opartą o przełączanie widoków (view- switching navigation),
- Prism’owe rozszerzenia dla MVVM (o ile będą lepsze od tego co sobie wypracowałem do tej pory).
Będę także przekazywał wystarczające minimum informacji by zacząć pracę z Prism. Po resztę szczegółów dotyczących wykorzystywanych funkcjonalności odsyłam do dokumentacji.

Bootstraper - koncepcja

SketchFlow - nowy projekt


Kluczowym elementem dla modułowej aplikacji wykorzystująca Prism jest Bootstraper.
Zadaniem jego jest inicjalizacja narzędzi podstawowych tj.:
- kontener DI – Prism oferuje nam Unity oraz MEF (jeśli chcemy, możemy z łatwością zaimplementować inny kontener),
- agregatora zdarzeń – odpowiedzialny za komunikację pomiędzy „luźno powiązanymi” modułami,
- menadżerów regionów, logowania, wyjątków,
Dodatkowo rejestruje w kontenerze DI wszelkiego rodzaju interfejsy implementowane przez powyższe narzędzia.
Po wykonaniu powyższych zadań, Bootstraper inicjalizuje Shell, który jest niczym innym jak głównym widokiem aplikacji zawierającym regiony do których będą wczytywane widoki, style i zasoby wykorzystywane przez całą aplikację. Poprzez analogię, Shell można porównać do ASP.NET-owego MasterPage.

Kod warty więcej niż 1000 słów
Inicjalizacja Bootstrapera odbywa się w App.xaml.cs

private void Application_Startup(object sender, StartupEventArgs e)
{
    var bootstrapper = new Bootstrapper();
    bootstrapper.Run();
}

A tak wygląda kod Bootstrapera

public class Bootstrapper : UnityBootstrapper
{
    private readonly CallbackLogger callbackLogger = new CallbackLogger();
 
    /// 
    /// Utworzenie widoku Shell
    /// ServiceLocator przejmuje funkcję Container.Resolve<IType>()
    /// opakowując kontener DI
    /// 
    protected override DependencyObject CreateShell()
    {
        return ServiceLocator.Current.GetInstance<MainPage>();
    }
 
    /// 
    /// Zainicjalizowanie głównego widoku
    /// 
    protected override void InitializeShell()
    {
        base.InitializeShell();
        Application.Current.RootVisual = (UIElement)this.Shell;
    }
 
    /// 
    /// Utworzenie własnego loggera 
    /// 
    protected override ILoggerFacade CreateLogger()
    {
        return this.callbackLogger;
    }
 
    /// 
    /// Konfiguracja kontenera DI: inicjalizacja Unity oraz mapowanie interfejs- typ np. IEventAggregator
    /// 
    protected override void ConfigureContainer()
    {
        base.ConfigureContainer();
        this.Container.RegisterInstance(this.callbackLogger);
        this.Container.RegisterType<ICustomerDetailsView, CustomerDetailsView>();
        this.Container.RegisterType<ICustomerDetailsViewViewModel, CustomerDetailsViewViewModel>();
        this.Container.RegisterType<IErrorWindow, ErrorWindow>();
        this.Container.RegisterType<IUnitOfWorkFactory, BasicUnitOfWorkFactory>();
        this.Container.RegisterType(typeof(IRepository<>), typeof(BasicRepository<>));
    }
 
    /// 
    /// Utworzenie katalogu modułów na podstawie pliku XAML
    /// 
    protected override IModuleCatalog CreateModuleCatalog()
    {
        return ModuleCatalog.CreateFromXaml(new 
         Uri("/MVVMBasic;component/ModulesCatalog.xaml", UriKind.Relative));
    }
}


Tak jak zapowiadałem, DevPrototype zawiera wszystkie powyższe zmiany prezentowane w tym poście (http://devprototype.codeplex.com)

Brak komentarzy:

Prześlij komentarz