Overview of the Composite Application
Guidance for WPF
Adam Calderon
Application Development Practice Lead
Contact Information
• More info on InterKnowlogy:www.InterKnowlogy.com
• Contact InformationE-mail: [email protected]: 760-930-0075 x274Blog: http://blogs.InterKnowlogy.com/AdamCalderon
• About Adam Calderon• Microsoft MVP – C#• Microsoft UI Server Frameworks Advisory Council• Developer / Author / Speaker / Teacher
Agenda
• What you can produce with CAL• Key concepts of a CAL application• How you can find out more?
Modules
• Provide a way to isolate functionality that can be used in many areas
• Enhances team development• Common Usages
• Specific application feature such as news
• Specific subsystem such as purchasing, invoicing, and general ledger
• Infrastructure services such as logging and authorization services or Web services
Static Module Loading
public class MyBootstrapper : UnityBootstrapper{ ... protected override IModuleEnumerator GetModuleEnumerator() { return new StaticModuleEnumerator() .AddModule(typeof(SomeModule)) .AddModule(typeof(AnotherModule), "SomeModule") .AddModule(typeof(YetAnotherModule), "AnotherModule","SomeModule"); }}
Module Dependencies
Module type
Locates modulesReturns statically
referenced modules
public class SomeModule : IModule public SomeModule(SomeDependency myDependency) {...} public void Initialize() { RegisterViewsAndServices(); //Show views here; }}
Module Initialization
Dependency injected
Initialization logic"Have it your way"
Dynamic Module Loading
public class MyBootstrapper : UnityBootstrapper{ ... protected override IModuleEnumerator GetModuleEnumerator() { return new StaticModuleEnumerator() .AddModule(typeof(SomeModule)) .AddModule(typeof(AnotherModule), new[] {"SomeModule“}) .AddModule(typeof(YetAnotherModule), new[] { "AnotherModule" }) }}
public class MyBootstrapper : UnityBootstrapper{ ... protected override IModuleEnumerator GetModuleEnumerator() { return new DirectoryLookupModuleEnumerator(@".\Modules"); }}
Scans folders for modules
Regions and Views
• Regions contain content that is dynamically added
• Modules insert content into regions• Views can consist of User Controls or
data that contains an associated data template
Region Registration
MyShell.xaml
RegionName attached property
Most Regions are ItemsControls
<TabControl x:Name="OrderTab" ItemContainerStyle="..." cal:RegionManager.RegionName="OrderRegion" />
Views as User Controls
public class MyModule : IModule{ public void Initialize (IRegionManager manager) { RegisterViewsAndServices();
IRegion orderRegion = manager.GetRegion("OrderRegion"); var myOrderView = new OrderView(myOrder); orderRegion.Add(myOrderView); }}
Region manager is needed
View is created
Region is retrieved
View is shown
Views Represented by Templates
public class MyModule : IModule{ public void Initialize(IRegionManager manager) { RegisterViewsAndServices();
IRegion orderRegion = manager.GetRegion("OrderRegion"); orderRegion.Add(myOrder); }}
Order is added directly
Commands
• Routed Commands can introduce issues in composite applications
• Delegate Commands don’t bubble up through element tree
• Composite Commands provide a mechanism to call 1..n Delegate Commands
Composition Commands
Submit
OrderDetails
Submit
OrderDetails
Submit
OrderDetails
Submit All
Delegate Commands
Composite Command
Building a Composite Command
<StackPanel Orientation="Horizontal"> <Button Name="SubmitAllToolbarButton" Command="{x:Static inf:Commands.SubmitOrdersCommand}"> Submit All </Button></StackPanel
Wire up the Command
Registering a Child Command
Connecting the childto the parent
public class OrderDetailsPresenter : IOrderDetailsPresenter{ private ICommand orderSubmitCommand;
public OrderDetailsPresenter(...) { orderSubmitCommand = …
// Register the command Commands.SubmitOrdersCommand.RegisterCommand(orderSubmitCommand); }}
Handling the Command
public class OrderDetailsPresenter : IOrderDetailsPresenter{ private ICommand orderSubmitCommand;
public OrderDetailsPresenter (IOrderDetailsView view, { orderSubmitCommand = new DelegateCommand(Submit, CanSubmit);
// Register the command
Commands.SubmitOrdersCommand.RegisterCommand(orderSubmitCommand);
}
public void Submit(object params) {...}
public bool CanSubmit(object params) {...}
}
Handling the canExecute and
Execute
Events
• Event Aggregation allows for decoupling of events
• Provides a mechanism that allows newly added modules to subscribe to events from other parts of application
• Implemented as a service
Event Aggregation
EventAggregatorService
OrderReceived
OrderManager
OrderListPresenter
Subscribes
OrderModule
OrderService
Publishes
Receives
Event Aggregation – The Event
public class OrderReceivedEvent : CompositeWPFEvent<Order>
{ …..}
Decouples publisher and subscriber
Event Aggregation-Subscription
public class SomePresenter { public SomePresenter(IEventAggregator eventAggregator) {• //subscribing to the event eventAggregator.Get<OrderReceivedEvent>(). Subscribe(OnOrderReceived, ThreadOption.UIThread); }
private void OnOrderReceived(Order order) { ... }}
Repository for events
Retrieving the event
Subscribing to the event
Dispatching to the correct
thread
Event Aggregation-Subscription 2
public class SomePresenter { public SomePresenter (IEventAggregator eventAggregator) { //subscribing to the event eventAggregator.Get<OrderReceivedEvent>(). Subscribe(OnOrderReceived, ThreadOption.UIThread, false, o=>o.Priority == Priority.High);
); }
private void OnOrderReceived(Order order) { ... }}
Keep the subscriber alive
Subscription filter Predicate<T>
Event Aggregation-Publish
public class OrderService : IOrderService { public OrderService(IEventAggregator eventAggregator) {...}
private void OrderReceived(Order) { //publish EventAggregator.Get<OrderReceivedEvent>(). Publish(Order); }}
Publish the event
Capabilities and Features
•Region Manager•Region Attached Properties•MVP / Presentation Model
Regions and Views
•Static•Directory Sweep•Configuration Driven•On-Demand
Module Loading
•Event Aggregator•Composite Command•Delegate Command•Active Aware Composite Command•Active Aware Delegate Command
Communication
Contact Information
• More info on InterKnowlogy:www.InterKnowlogy.com
• Contact InformationE-mail: [email protected]: 760-930-0075 x274Blog: http://blogs.InterKnowlogy.com/AdamCalderon
• About Adam Calderon• Microsoft MVP – C#• Microsoft UI Server Frameworks Advisory Council• Developer / Author / Speaker / Teacher