Olá pessoal, tudo certo?
Atualmente, estou envolvido num projeto que avalia uma interface de composição e seus desafios. Existem diversos aspectos de arquitetura envolvidos nesse tipo de interface, como:
Para atender esses requisitos, existem diversos patterns aplicáveis, como:
Como alternativa na plataforma Microsoft estou usando o PRISM v2.0 - Composite Application Guidance for WPF and Silverlight 2.0, anunciado recentemente, veja aqui.
Assim, os próximos posts serão dedicados ao PRISM v2.0 e seus recursos.
Para começar, a figura ao lado apresenta a pilha de componentes do PRISM, que executa sobre o .NET 3.5 e os recursos do WPF - Windows Presentation Foundation.
Entre os componentes principais citamos: o Unity Application Block, responsável pela infra-estrutura para inversão de controle e tratamento de containers; o Unity Extensions Composite Application Library, que disponibiliza os recursos da Unity no ambiente de programação do PRISM; e a própria Composite Application Library (CAL), que encapsula esses recursos para o desenvolvedor PRISM.
Sobre a CAL, criamos nossos módulos e shell interface para a aplicação de composição.
Já no desenvolvimento de nossos módulos e elementos de tela, a CAL oferece o seguinte conjunto de recursos:
Seu primeio projeto com o PRISM v2.0
Vejamos um primeiro projeto com o PRISM. O pacote possui diversos projetos prontos que são boas dicas de estudo, entre eles, vários Quick Starts sobre cada um dos componentes da CAL. Vamos olhar hoje o Quick Start "Hello World". Ele se encontra instalado na pasta abaixo:
C:\[PRISM V2.0]\Quickstarts\Hello World\HelloWorld.Desktop
Abrindo o QuickStart "Hello World", você terá a seguinte solução no Visual Studio:
Na figura ao lado, vemos 1 pasta para os componentes da CAL (Composite.Desktop, Composite.Presentation.Desktop e Composite.UnityExtensions.Desktop), assim como 2 projetos na solução:
Portanto, uma solução com o PRISM terá no mínimo 2 projetos: a interface principal (sendo o ponto de entrada) e um módulo de visualização.
Quando olhamos o projeto do HelloWorldModule, notamos que nenhuma referência é feita para o projeto Desktop. Ao mesmo tempo, temos uma pasta de View(s) presente no projeto, implementando os componentes de tela do módulo. Uma View é na verdade um User Control em WPF que será apresentado na interface shell, como vemos abaixo:
Em XAML, esse User Control aparece assim:
1: <UserControl x:Class="HelloWorldModule.Views.HelloWorldView"
2: xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3: xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
4: <Grid>
5: <TextBlock Text="Hello World - Arquitetura de Soluções" Foreground="Green" HorizontalAlignment="Center" VerticalAlignment="Center" FontFamily="Calibri" FontSize="24" FontWeight="Bold"></TextBlock>
6: </Grid>
7: </UserControl>
Encapsulando essa View no Módulo HelloWorld, vemos a classe HelloWorldModule, apresentada a seguir a partir do arquivo "HelloWorldModule.cs". Note que através dessa classe, relacionamos as views presentes no módulo, assim como a região que usaremos na interface principal para apresentação da view:
1: using Microsoft.Practices.Composite.Modularity;
2: using Microsoft.Practices.Composite.Regions;
3:
4: namespace HelloWorldModule
5: {
6: public class HelloWorldModule : IModule
7: {
8: private readonly IRegionViewRegistry regionViewRegistry;
9:
10: public HelloWorldModule(IRegionViewRegistry registry)
11: {
12: this.regionViewRegistry = registry;
13: }
14:
15: public void Initialize()
16: {
17: regionViewRegistry.RegisterViewWithRegion("MainRegion", typeof(Views.HelloWorldView));
18: }
19: }
20: }
Esse projeto compilado deverá gerar a biblioteca "HelloWorldModule.dll".
Olhando o projeto HelloWorld.Desktop presente na solução, vemos uma interface principal chamada Shell, que define a MainRegion, container para os vários módulos da solução.
O código XAML da Shell principal é dado a seguir:
1: <Window x:Class="HelloWorld.Shell"
3: xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4: xmlns:cal="http://www.codeplex.com/CompositeWPF"
5: Title="Hello World" Height="195" Width="316">
6: <ItemsControl Name="MainRegion" cal:RegionManager.RegionName="MainRegion" />
7: </Window>
No XAML acima vemos a definição do MainRegion, através da chamada cal:RegionManager.RegionName = "MainRegion". Nesse ponto, fazemos a associação da região para visualização do módulo criado.
Finalmente, o projeto HelloWorld.Desktop implementa uma classe importante chamada "Bootstrapper". Ela é o ponto de entrada da CAL na aplicação, sendo responsável pela enumeração e carga dos módulos participantes da solução.
No código abaixo, vemos o método GetModuleCatalog(), onde o módulo HelloWorldModule é chamado:
1: namespace HelloWorld
2: {
3: class Bootstrapper : UnityBootstrapper
4: {
5: protected override DependencyObject CreateShell()
6: {
7: Shell shell = new Shell();
8: shell.Show();
9: return shell;
10: }
11:
12: protected override IModuleCatalog GetModuleCatalog()
13: {
14: ModuleCatalog catalog = new ModuleCatalog()
15: .AddModule(typeof(HelloWorldModule.HelloWorldModule));
16: return catalog;
17: }
18:
19:
21: }
Uma vez compilado, o projeto HelloWorld.Desktop deverá gerar o executável "HelloWorld.exe", que consome o módulo HelloWorldModule.dll.
Ao final, a aplicação executada apresenta a seguinte interface:
Como exercício sobre esse projeto, execute passo-a-passo a solução e verifique a ordem de disparo de cada um dos componentes da CAL. Você verá a primeira chamada para a class App : Application, seguida pela class Bootstrapper : UnityBootstrapper, etc. Vale conferir.
Nos próximos posts, vamos falar de cada um desses componentes, enquanto percorremos os HOW TO'S, Quick Starts e demais artigos presentes no Prism v2.0.
Por enquanto é só! Até o próximo post :)
Waldemir.