Claudio Lassala Software Developer EPS Software / CODE Magazine Session Code: DEV 201
Download ReportTranscript Claudio Lassala Software Developer EPS Software / CODE Magazine Session Code: DEV 201
Claudio Lassala Software Developer EPS Software / CODE Magazine Session Code: DEV 201 Who Am I? Claudio Lassala Blog: ClaudioLassala.spaces.live.com [email protected] twitter.com/ClaudioLassala Microsoft MVP for the last 9 years INETA Speaker International Speaker and Writer Virtual Brown Bag Meeting Developer @ EPS Software About EPS Software Custom Software Development Consulting / Mentoring Training WPF .NET CODE Magazine What is a “Composite” Application? Application that may Use different data sources (web services, local data..) Combine multiple modules Have composite “views” (screens) Composite Application Samples The Challenge Composite Application Guidance for WPF and Silverlight Prism: What’s in the box? Prism – Composite Client Application Guidance for WPF and Silverlight Composite Application Library (CAL) Reference Implementation (StockTrader) Documentation Quick-Starts & How-To’s Community – CodePlex www.microsoft.com/CompositeWPF Prism Core Concepts Module Loading UI Composition View Injection and View Discovery Events Commands Optional (but recommended) Bootstrapper DI/IoC Container Separated Presentation DI/IoC Container var container = new UnityContainer() container.RegisterType<IShellView, Shell>(); var view = container.Resolve<IShellView>(); public class Shell { public Shell(ISomeService someService) { } } Bootstrapper public partial class MyAppBootstrapper : UnityBootstrapper { protected override IModuleCatalog GetModuleCatalog() { // register modules with catalog… } protected override void ConfigureContainer() { // Register types with container… } protected override DependencyObject CreateShell() { // resolve shell and show it… } } Separated Presentation Patterns Supervising Controller Presentation Model / Model-View-ViewModel View Presenter View Model View Model Model Module Loading Implement IModule Tell Prism how to go find it Implementing IModule public class ModuleA : IModule { private readonly IRegionManager regionManager; public ModuleA(IRegionManager regionManager) { this.regionManager = regionManager; } public void Initialize() { this.regionManager.Regions["MainRegion"] .Add(new DefaultViewA()); } } Loading Modules ModuleCatalog catalog = new ModuleCatalog(); catalog.AddModule(typeof (ModuleA), "ModuleD") .AddModule(typeof (ModuleD), "ModuleB") .AddModule(typeof (ModuleC), InitializationMode.OnDemand); private void SomeMethod(IModuleManager moduleManager) { moduleManager.LoadModule("ModuleC"); } UI Composition View Injection View Discovery Region Manager Definition Regions <ContentControl cal:RegionManager.RegionName = "ToolbarRegion" /> <ItemsControl cal:RegionManager.RegionName = "MainRegion" /> ToolbarRegion MainRegion View Discovery public void Initialize() { this.regionManager.RegisterViewWithRegion("MainRegion", () => container.Resolve<IEmployeesPresenter>().View); } View Injection public void Initialize() { var presenter = this.container.Resolve<IEmployeesPresenter>(); IRegion mainRegion = this.regionManager.Regions["MainRegion"]; mainRegion.Add(presenter.View); } Commands Delegate Command Composite Command Hooking Up Commands // Delegate Command <Button Content="Save" Command="{Binding SaveOrderCommand}" /> // Composite Command <Button Content="Save All" Command="{x:Static inf:OrdersCommands.SaveAllOrdersCommand}" /> Handling Delegate Command public DelegateCommand<object> SaveOrderCommand { get; private set; } public OrderPresentationModel() { this.SaveOrderCommand = new DelegateCommand<Order>(this.Save, this.CanSave); } private void Save(Order order) { // Save the order here. } private bool CanSave(Order order) { return order.IsValid(); } Defining Composite Commands public static class OrdersCommands { public static CompositeCommand SaveAllOrdersCommand = new CompositeCommand(); } public class OrdersCommandProxy { public virtual CompositeCommand SaveAllOrdersCommand { get { return OrdersCommands.SaveAllOrdersCommand; } } } Wiring Composite Commands commandProxy.SaveAllOrdersCommand.RegisterCommand( orderPresentationModel.SaveOrderCommand); Save All Order Save Order Save Order Save Events Loosely Coupled Events Subscribers and Publishers don't know about it other Threading Support Subscription Filter Weak Reference Defining Composite Events public class FundAddedEvent : CompositePresentationEvent<FundOrder> { } public class FundOrder { public string CustomerId { get; set; } public string TickerSymbol { get; set; } } Publishing Composite Events public AddFundPresenter(IEventAggregator eventAggregator) { this.eventAggregator = eventAggregator; } void AddFund(object sender, EventArgs e) { FundOrder fundOrder = new FundOrder(); fundOrder.CustomerId = View.Customer; fundOrder.TickerSymbol = View.Fund; eventAggregator.GetEvent<FundAddedEvent>() .Publish(fundOrder); } Subscribing To Composite Events var fundAddedEvent = eventAggregator.GetEvent<FundAddedEvent>(); fundAddedEvent.Subscribe(FundAddedEventHandler); public void FundAddedEventHandler(FundOrder fundOrder) { // process fund order… } Subscribing To Composite Events var fundAddedEvent = eventAggregator.GetEvent<FundAddedEvent>(); fundAddedEvent.Subscribe(FundAddedEventHandler, ThreadOption.UIThread, false, FundOrderFilter); public void FundAddedEventHandler(FundOrder fundOrder) { // process fund order… } public bool FundOrderFilter(FundOrder fundOrder) { return fundOrder.CustomerId == _customerId; } The Shell Always put some thought into what elements the Shell should have What the elements look like can be defined or changed later Toolbar Region Navigation Region Main Region Extra Info Region Infrastructure An “infrastructure” project should contain crosscutting plumbing/features That is, anything required by the application as a whole, or required by more than one module Key abstractions go there Modules Usually, one project per module Single Project could have multiple modules organized by namespace Harder to manage dependencies between modules Compiling separate projects into a single DLL is easy; going the other way around, not so much! Views, ViewModels, Controllers, “application services”… Looking at a Composite Application Call to Action Poke around this sample application Read Prism’s documentation Resources www.microsoft.com/teched www.microsoft.com/learning Sessions On-Demand & Community Microsoft Certification & Training Resources http://microsoft.com/technet http://microsoft.com/msdn Resources for IT Professionals Resources for Developers More Resources See my article on CODE magazine (2009 Jul/Aug) www.microsoft.com/CompositeWPF Complete an evaluation on CommNet and enter to win an Xbox 360 Elite! © 2009 Microsoft Corporation. All rights reserved. Microsoft, Windows, Windows Vista and other product names are or may be registered trademarks and/or trademarks in the U.S. and/or other countries. The information herein is for informational purposes only and represents the current view of Microsoft Corporation as of the date of this presentation. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information provided after the date of this presentation. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.