Posts Tagged ‘prism’

Prism 2: WPF and Silverlight – Commands

May 20th, 2009

prism

This post is part of a Prism 2 series:

Prism 2: WPF and Silverlight – Inversion of Control
Prism 2: WPF and Silverlight – Multi Platform Targeting
Prism 2: WPF and Silverlight – Modularity
Prism 2: WPF and Silverlight – Model-View-ViewModel
Prism 2: WPF and Silverlight – View Injection/View Discovery
Prism 2: WPF and Silverlight – Commands
Prism 2: WPF and Silverlight – Events
Prism 2: WPF and Silverlight – Services

Commands and MVVM
When working with MVVM pattern we quickly reach the point when using WPF commands is not a good option because Wpf commands are tied to the logical tree meaning that they cannot be handled outside of the view.
This has big impact on unit testing and components design. What we really want is to move command handling code from View to ViewModel. Unlike Wpf commands, commands in Prism can be handled outside of the logical tree in a loosely coupled way enabling better separation of concerns.
There are two command types in Prism (both implement ICommand interface): DelegateCommand and CompositeCommand.

DelegateCommand<T>

We use DelegateCommand to delegate handling logic to the ViewModel.
Let’s say that we want to create login screen for our application.
We may start from creating a ViewModel:

   1: public class LoginViewModel   

   2: {   

   3:     private DelegateCommand<string> loginCommand;   

   4:  

   5:     public DelegateCommand<string> LoginCommand   

   6:     {   

   7:         get { return loginCommand; }   

   8:         private set { loginCommand = value; }   

   9:     }  

  10:  

  11:     public LoginViewModel()  

  12:     {  

  13:         this.LoginCommand = new DelegateCommand<string>(Login, CanLogin);  

  14:     }  

  15:  

  16:     void Login(string userName)  

  17:     {  

  18:         Debug.WriteLine("working..");  

  19:     }  

  20:     

  21:     bool CanLogin(string userName)  

  22:     {  

  23:         return !string.IsNullOrEmpty(userName);  

  24:     }  

  25: }

As we can see, property of type DelegateCommand<string> has been created.

This command expects a string parameter (user name).

When creating command, we pass two delegates to the constructor:

   1: // DelegateCommand constructor:   

   2: public DelegateCommand(Action<T> executeMethod, Func<T, bool> canExecuteMethod) { .. }   

   3:  

   4: // DelegateCommand initialization:   

   5: this.LoginCommand = new DelegateCommand<string>(Login, CanLogin);

First one (Login) will be called when command executes.

Second one (CanLogin) will be called to check whether command can execute.

CanLogin simply checks if userName is null or empty, and if it is, command won’t execute (and Login button will be disabled)

This is how our view may look like:

   1: xmlns:commands="clr-namespace:Microsoft.Practices.Composite.Presentation.Commands;assembly=Microsoft.Practices.Composite.Presentation"  

   2:      

   3: <StackPanel>   

   4:         <TextBlock Text="UserName:"/>   

   5:         <TextBox x:Name="UserNameInput" />   

   6:         <Button Content="Login"    

   7:                 commands:Click.Command="{Binding LoginCommand}"    

   8:                 commands:Click.CommandParameter="{Binding Text, ElementName=UserNameInput}" />   

   9:     </StackPanel>

Looking at the code above we see that Login Button has a binding to LoginCommand (commands:Click.Command="{Binding LoginCommand}" ) and we pass the content of user name text box as a parameter to the command (commands:Click.CommandParameter="{Binding Text, ElementName=UserNameInput}").

When we run the test solution (link at the bottom of this post), we’ll see that Login button is disabled (UserNameInput textbox is empty)

comm1

Login button will be enabled as soon as we type a user name and command will execute when Login button is clicked.

comm2

CompositeCommand

CompositeCommand is a command that contains multiple other commands.

CompositeCommand can execute only when all child commands can execute



IActiveAware

IActiveAware interface (implemented by DelegateCommand) is used in scenarios when we want command to be executed only if it’s in an active view.

Compositecommand takes monitorCommandActivity parameter in it’s constructor, when set to true, CompositeCommand will execute commands that implement IActiveAware and have IsActive property set to true. Commands that do not implenet IActiveAware will be executed as well.

This logic can be changed by overriding ShouldExecute() method.

It’s comes in handy when implementing commands such as SaveAll or CloseAll.

Silverlight Support

Prism Commands are supported by Silverlight (unlike Wpf commands).

By default this is enabled on controls that inherit from ButtonBase but we can write custom Attached Behaviors to support other controls and commands.

I’ll write about this technique in the nearest future.

Playground

Solution that shows Command support in Silverlight can be downloaded here.

– COMMENTS FROM PREVIOUS BLOG:

31/07/2009 02:48:07 #

Hi. Your example is useful but simplistic. In any login scenario, a password must be provided as well as the username. If we are to follow the same logic, then we would need to pass 2 parameters to the command. From what I can tell, there’s no way to do that with the current classes in Prism. Or am I wrong?

One solution that I can think of is to ignore the CommandParameter, and just bing to username and password UI elements values to the corresponding properties in the view model. Then, when the command is invoked, the values of the properties are verified, so no parameters are needed. I’m not sure if it’s a good practice, though. What do you think of this? Or please suggest a different approach.

blackjack2150

31/07/2009 03:04:04 #

mokosh

Hi blackjack,

This is exactly what I do in situations you just described (and quite often when I have only one parameter too) – just skip the param and read all you need from the properties in viewmodel.

mokosh

05/09/2009 02:56:30 #

Am I missing something? I thought in order to support binding a couple of things need to happen.

1) Your view model needs to inherit from DependencyObject or some object higher up in the food chain.

2) Your DelegateCommand<T> should be a dependency property (as well as any properties that you will use as parameters for the command outside of using the CommandParameter attached property)

Ryan Haney

05/09/2009 03:08:35 #

Also, every time the state changes for your "can execute command" function, you need to force a requery. In the case of dependency properties, you can do this as such:

public static readonly DependencyProperty UsernameProperty =

DependencyProperty.Register("Username", typeof(string), typeof(LoginViewModel), new PropertyMetadata(new PropertyChangedCallback(

(d, e) => {

LoginViewModel vm = d as LoginViewModel;

vm.LoginCommand.RaiseCanExecuteChanged();

})));

Ryan Haney

Buy me a coffee to sponsor more posts like this!

Silverlight 3 – Application Services

May 13th, 2009

puzzle1

In SL3 there is a new possibility of creating central repository of services with application controlled life time and easy access from anywhere in the code.
Creating Application Service
All application services have to implement IApplicationService interface.
This interface exposes two methods: StartService and StopService.
StartService method has access to ApplicationServiceContext parameter which we can use to check whether application is running in offline mode or to get initialization parameters.
Additionally our service can implement IApplicationLifetimeAware interface which exposes more methods: Starting, Started, Exiting, Exited

   1: public class MyService : IApplicationService, IApplicationLifetimeAware   

   2: {   

   3:     Dictionary<string, string> InitializationParameters;   

   4:     

   5: #region IApplicationService Members   

   6:      

   7:      public void StartService(ApplicationServiceContext context)   

   8:      {   

   9:          this.InitializationParameters = context.ApplicationInitParams;  

  10:      }  

  11:     

  12:      public void StopService() { }  

  13:     

  14: #endregion  

  15:     

  16: #region IApplicationLifetimeAware Members  

  17:  

  18:     public void Exited() { }  

  19:     public void Exiting() { }  

  20:     public void Started() { }  

  21:     public void Starting() { }  

  22:     #endregion  

  23: }

Methods in service and our Application are called in following sequence:

StartService (IApplicationService)

Starting (IApplicationLifetimeAware)

Application_Startup (Application object)

Started (IApplicationLifetimeAware)

Exiting (IApplicationLifetimeAware)

Application_Exit (Application object)

Exited (IApplicationLifetimeAware)

StopService (IApplicationService)

Services must be added to application in App.Xaml:

   1: <Application.Services>   

   2:         <appsvc:WebUserService x:Name="UserService" />   

   3: </Application.Services>

NOTE: Adding services from code during application runtime will result in exception:

 

   1: Application.Current.Services.Add("UserService", new WebUserService()); // Will throw exception

How does it compare to services in context of Prism



(To read more about Prism services go here)

There are few differences between how Application Services and Prism Services work.

1. Service Registration

In Prism:

    We have to register the service with lightweight container (Unity by default), Services can be registered at any moment during application lifetime

   1: Container.RegisterInstance<IMyService>(new MyService());

In Application Services:

    We have to register services in App.Xaml  
2. Accessing Services

In Prism:

    Services can be injected to our classes using Dependency Injection Pattern (described here) or located using ServiceLocator:

   1: ServiceLocator.Current.GetInstance<IMyService>();   

   2:  

   3: // or if we have multiple instances of same service each with different name:   

   4:  

   5: ServiceLocator.Current.GetInstance<IMyService>("MyService1");

In Application Services:

    Services can be accessed using Application Class

   1: IMyService myService = Application.Current.Services["MyService"] as IMyService;

We can see that Prism provides more flexibility in how we access services and we only need to know the interface implemented by service (but we can name our services as well if we choose to)

In case of Application Services we need to know both interface and name of a service.

3. Application awareness and lifetime

In Prism:

    Our services have limited knowledge about application lifetime.

    They can access Application.Current object.

    They can check whether application is running offline at any time by calling NetworkInterface.GetIsNetworkAvailable() method.

In Application Services:

    Our services have full exposure to application lifetime.

    They can access Application.Current object.

    They have access to information such as Application Initialization Parameters or whether application is running in offline mode in StartService method.

    They can check whether application is running offline at any time by calling NetworkInterface.GetIsNetworkAvailable() method.

As we can see main advantage of Application Services is the app lifetime awareness.

It’s probably not something we’re going to use very often, but if we need this functionality and access to initialization parameters than this is the way to go.

In all other cases I would stick to handling services in Prism-like fashion as it seems more flexible.

Buy me a coffee to sponsor more posts like this!

Prism 2: WPF and Silverlight – Services

April 19th, 2009

prism

This post is part of a Prism 2 series:

Prism 2: WPF and Silverlight – Inversion of Control
Prism 2: WPF and Silverlight – Multi Platform Targeting
Prism 2: WPF and Silverlight – Modularity
Prism 2: WPF and Silverlight – Model-View-ViewModel
Prism 2: WPF and Silverlight – View Injection/View Discovery
Prism 2: WPF and Silverlight – Commands
Prism 2: WPF and Silverlight – Events
Prism 2: WPF and Silverlight – Services

One of the Prism’s strengths is it’s extensibility achieved by use of Services.
Services are just instances of classes that are supposed to provide some functionality like logging or authenticating users.
Some of core services in Prism are:

  • IModuleCatalog
  • ILoggerFacade
  • IServiceLocator


Creating Services

Lets look at Emotwittion as an example, it uses two custom services:

  • IGeoLocationService – to get longitude and latitude of a place in a world
  • ITwitterMonitorService – to get status updates from Twitter

There are two places where we would typically register our custom services: in Bootstrapper or in Module Initialization method.
Most of the times we want only one instance of our service to exist, and this is easy to accomplish using Unity Container:

   1: Container.RegisterInstance<IGeoLocationService>(new GeoLocationService());

If we need several instances of a service, we can use overloaded method and name our instance:

   1: Container.RegisterInstance<IGeoLocationService>("GeoLocationServiceOne", new GeoLocationService());   

   2: Container.RegisterInstance<IGeoLocationService>("GeoLocationServiceTwo", new OtherGeoLocationService())

We can later get the desired instance of a service using Service Locator or Dependency Injection (described in more details here):

   1: ServiceLocator.Current.GetInstance<IGeoLocationService>("GeoLocationServiceTwo");

Async vs. Sync

It is very tempting to create synchronous services (because is much easier and straightforward), but if we really want to share services between Wpf and Silverlight we should use Asynchronous model, not only because it’s more efficient, but also because we may be forced to do so if service we try to develop calls WebServices (which are accessible in Async way only in SL).

I’d suggest following these rules:

Each asynchronous method should have Async in a name and event fired on completition with a name following <methodname>Completed pattern:

   1: public event EventHandler<Mokosh.Core.AsyncCompletedEventArgs<Location>> GetLocationByLocationNameCompleted;   

   2:      

   3: public void GetLocationByLocationNameAsync(string locationName, object userState);

As we can see above, GetLocationByLocationNameAsync method expects userState parameter which can be used by caller to identify a call (task Id) or store some context information to be retrieved when handling GetLocationByLocationNameCompleted event.

Closer look at the AsyncOperationEventArgs<T> will reveal that it contains property named Error of type System.Exception (same as System.ComponentModel.AsyncCompletedEventArgs class). This can be used by caller to get error information if something goes wrong.

Cross-Modules communication using Shared Services

We discussed how modules can communicate using EventAggregator before.

Another method of cross-module communication is through shared services.

We can use Inversion of Control pattern to obtain global (shared) instance of a service and use it to share data and pass messages between modules.

Playground

You can download Emotwittion Solution here here.

Buy me a coffee to sponsor more posts like this!

Prism 2: WPF and Silverlight – Events

April 19th, 2009

prism

This post is part of a Prism 2 series:

Prism 2: WPF and Silverlight – Inversion of Control
Prism 2: WPF and Silverlight – Multi Platform Targeting
Prism 2: WPF and Silverlight – Modularity
Prism 2: WPF and Silverlight – Model-View-ViewModel
Prism 2: WPF and Silverlight – View Injection/View Discovery
Prism 2: WPF and Silverlight – Commands
Prism 2: WPF and Silverlight – Events
Prism 2: WPF and Silverlight – Services

In modular applications it is quite often required that modules communicate without directly depending on each other.
In Prism 2 world this can be achived using Event Aggregation Service. We will use this service when we need to publish an event accross modules and do not need a response.
Few points worth remembering:

  • Publisher and Subscriber do not directly depend on one another
  • Publisher calls Event Aggregation Service in order to publish notifications
  • Subscriber observes specific events it is interested in

Event Aggregator
EventAggregator is a service that holds a repository of event objects (EventBase).
Event objects use delegates instead of .Net events to ensure that Publisher and Subscriber do not have to reference each other directly.
Each Event object contains a collection of subscribers and can automatically handle marshaling to correct thread.
The great thing about EventAggregator is that it constructs the event on its first access, even when it hasn’t been created yet.
This way subscribers don’t have to wait for publisher to register the event – once publisher does that they will be notified – it means No Timinng Issues.

eventag

Defining Event
In Emotwittion we want Module1 to publish an event every time new Twitter Status is retreived.
We also want LoggingModule to subscribe to this event and store the status in text file on hard drive.
We mentioned EvenBase before, in Prism 2 the only concrete implementation of this class is CompositePresentationEvent and all our events have to inherit from it:

   1: public class TwitterStatusRetrievedEvent : CompositePresentationEvent<TwitterStatusEmoInfo>   

   2: {   

   3: }

To allow other modules to use our events we will declare them in <module>.Infrastructure project that can be shared between modules.

Publisher

Publishing events is realy easy, all we have to do is to use EventAggregator to get the CompositePresentationEvent and call it’s Publish() method:

   1: TwitterStatus status = GetNextTwitterStatus();    

   2:  

   3: EventAggregator.GetEvent<TwitterStatusRetrievedEvent>().Publish(status);

Subscriber

To subscribe to an Event, we have to get it from EventAggregator and call it’s Subscribe() method.

There are few things to consider when subscribing for an event:

  • Thread – which thread should be used to process the event? There are three options available: BackgroundThread, PublisherThread and UIThread. We will use UIThread if we need to update user inferface when an event is received.
  • Filtering – we can filter out events we want to receive based on properties of event’s payload
  • Using Strong or Weak References – by default, CompositePresentationEvent maintains weak reference to subscriber’s handling method to avoid memory leaks. This means that reference that it holds will not prevent garbage collector from collecting the subscriber.

    For most applications this is what we really want, but if you publish large amouts of events very frequently, it may lead to poor performance. keepSubscriberReferenceAlive is the parameter of Subscribe() mathod that controls which (strong/weak) reference is being held.

    If we decide to keep subscriber reference alive, we’ll have to remember to unsubscribe from an event once we don’t need it anymore to avoid memory leaks.

Back to our example application, we want Twitter Statuses to be logged somewhere (Visual Studio Output Window in our case).

To do that we’ve created Emotwittion.LoggingModule and TwitterStatusLoggingService in it.

TwitterStatusLoggingService subscribes itself to the TwitterStatusRetreivedEvent:

   1: public TwitterStatusLoggingService(IEventAggregator eventAggregator)   

   2: {   

   3:     this.EventAggregator = eventAggregator;   

   4:     EventAggregator.GetEvent<TwitterStatusRetrievedEvent>().Subscribe(Log, Microsoft.Practices.Composite.Presentation.Events.ThreadOption.BackgroundThread);   

   5: }

and handles it by directing status info to the Debug output stream

   1: public void Log(TwitterStatusEmoInfo info)   

   2: {   

   3:     Debug.WriteLine(string.Format(InfoFormat, Environment.NewLine, info.StatusText, info.Location));   

   4: }

Playground

You can download Emotwittion Solution here here.

Buy me a coffee to sponsor more posts like this!

Prism 2: WPF and Silverlight – Regions and View Injection/View Discovery

April 19th, 2009

prism

This post is part of a Prism 2 series:

Prism 2: WPF and Silverlight – Inversion of Control
Prism 2: WPF and Silverlight – Multi Platform Targeting
Prism 2: WPF and Silverlight – Modularity
Prism 2: WPF and Silverlight – Model-View-ViewModel
Prism 2: WPF and Silverlight – View Injection/View Discovery
Prism 2: WPF and Silverlight – Commands
Prism 2: WPF and Silverlight – Events
Prism 2: WPF and Silverlight – Services

Modularity is a great thing, but how do modules know where to fit in a bigger scope?
If we want to present the view we’ve just created in new module, how do we tell our Shell (or other modules) about it?
Prism uses 3 concepts that will help us to achieve this: Regions, View Injection and View Discovery.
Regions

Region is a mechanism that allows us to expose part of user interface to modules, so that they can use it to present views.
It works like a placeholder for content that will be supplied later.
Regions can be added to Xaml controls in a declarative way, and are uniqely identified by their names:

   1: <Window x:Class="Shell.UIShell"   

   2:      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"   

   3:      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"   

   4:      xmlns:cal="clr-namespace:Microsoft.Practices.Composite.Presentation.Regions;assembly=Microsoft.Practices.Composite.Presentation"   

   5:      Title="UIShell" Height="800" Width="1000">   

   6:      <Grid>   

   7:          <Grid x:Name="LayoutRoot" Background="Black">   

   8:              <ItemsControl x:Name="MainRegion" cal:RegionManager.RegionName="MainRegion" />   

   9:              <TextBlock Text="www.mokosh.co.uk" Foreground="DarkRed" FontWeight="Bold" VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="25" />  

  10:          </Grid>  

  11:      </Grid>  

  12: </Window>

In the xaml above we declared a new namespace (xmlns:cal) and then decorated ItemsControl with cal:RegionManager.RegionName="MainRegion". This way we told RegionManager that our MainRegion is linked to ItemsControl.

By default, we can assign regions to controls of type ContentControl, Primitives.Selector, TabControl and ItemsControl.

If we ever need to decorate other types of control (we may use some 3rd party control libraries), we can always write our custom implementation of IRegionAdapter interface and register it with Prism.

In Prism v1 recommended practice was to use string consts declared in a custom class for region names:

   1: <ItemsControl cal:RegionManager.RegionName="{x:Static local:RegionNames.MainRegion}">

It still is a good practice, but unfortunately Silverlight doesn’t support x:Static in Xaml, so in situation when we want to reuse Xaml code we have to use hardcoded values instead.

View Injection

One way to populate region with a view is to use View Injection pattern.

In Initialize() method of our custom module, we use IRegionManager to get the region and then we Add new View to it:

   1: Views.TwitterMapView view = Container.Resolve<Views.TwitterMapView>();   

   2:      

   3: IRegion mainRegion = this.RegionManager.Regions[Regions.MainRegion];   

   4: mainRegion.Add(view);   

   5:      

   6: mainRegion.Activate(view);

Activate() method used above makes sure that our view will become visible after it’s injected to the region. It becomes useful when we use controls such as TabControl as Regions, and want tab that host the view to receive focus.

View Injection requires that requested Region exist when adding a View to it.

View Discovery

In situations when we cannot guarantee that Region has already been initialized, we can use View Discovery approach.

The idea is that each module uses RegionViewRegistry to register it’s views with a proper region.

When this region is created, it asks RegionViewRegistry for it’s views and registers for notification in case new views are added.

View to Region matching is based on Region Name, so to register TwitterMapView with MainRegion we will write:

   1: this.RegionManager.RegisterViewWithRegion(Regions.MainRegion, typeof(Views.TwitterMapView));

The type of a View we pass to RegisterViewWithRegion method will be used by Unity Container to resolve it’s instance and add it to the Region once it’s available.

It’s also worth mentioning that View First approach has been used in this case.

View First (as opposite to ViewModel First) means that View expects to get it ViewModel in a constructor (using Dependency Injection) and assigns it to it’s DataContext automatically:

   1: public TwitterMapView(Emotwittion.Module1.ViewModels.ITwitterMapViewModel dataContext)   

   2:              : this()   

   3: {   

   4:        DataContext = dataContext;   

   5: }

Playground

You can download Emotwittion Solution here here.

Buy me a coffee to sponsor more posts like this!

Prism 2: WPF and Silverlight – Model-View-ViewModel

April 19th, 2009

prism

This post is part of a Prism 2 series:

Prism 2: WPF and Silverlight – Inversion of Control
Prism 2: WPF and Silverlight – Multi Platform Targeting
Prism 2: WPF and Silverlight – Modularity
Prism 2: WPF and Silverlight – Model-View-ViewModel
Prism 2: WPF and Silverlight – View Injection/View Discovery
Prism 2: WPF and Silverlight – Commands
Prism 2: WPF and Silverlight – Events
Prism 2: WPF and Silverlight – Services

Prism 2 guidelines encourages us to use some sort of Separated Presentation Pattern.
Separated Presentation Pattern allows developers to separate user interface, presentation logic and business logic in a clean, organized way.
There are several benefits of using this pattern, it allows developers to work on application logic while designers work on UI, it makes application cheaper to modify and maintain and targeted to different platforms (in best scenario only UI part needs to be changed).
In this post we’ll have a closer look at one of Separated Presentation patterns – Model-View-ViewModel.

Model-View-ViewModel (MVVM)
is a special case of Presentation Model (PM) described here by Martin Fowler.
While Presentation Model is great for creating platform independent components, Model-View-ViewModel is standardized way to leverage features of Wpf/Silverlight to create user interfaces.
Main idea behind these patterns is to abstract the View. This abstraction is what we will call ViewModel (sometimes referred to as Presentation Model).

mvvm

There are few things to remember about this pattern:

  • View binds to properties on a ViewModel
  • User interaction with a View causes a Command to be executed on the ViewModel and ViewModel performs requested operation.
  • ViewModel does not need a reference to a view
  • ViewModel is set as DataContext of a view
  • ViewModel exposes data contained in Model
  • Only ViewModel can modify the Model data
  • Model is responsible for loading/string the data

Data binding
With data binding in wpf/silverlight controls automatically reflect changes to underlying data and can automatically update this data when user modifies it using user interface.
To support data binding, ViewModel and any properties provided to the view should implement INotifyPropertyChanged or INotifyCollectionChanged interface.
ViewModel is typically set as the data context for the view.
Commands
Commands represent actions that user can perform when interacting with user interface.
They provide declarative way of user interaction support, with commands being attached to user controls and underlying action being handled by ViewModel.
Data Templates
Data Templates define how data is presented to the user.
Main difference between Wpf and Silverlight is that in Wpf Data Templates can be declared on application level, while in Silverlight they have to be declared within the parent control.
Playground

In Emotwittion, TwitterMapView is a View, TwitterMapViewModel is a ViewModel and TwitterMonitor is a Model:

mvvm2

TwitterMapView uses DataTemplate to present Twitter statuses in ListBox, and Binding within the DataTemplate to get data from TwitterMapViewModel:

   1: <ListBox.ItemTemplate>  

   2:         <DataTemplate>   

   3:            <StackPanel Orientation="Horizontal" Margin="2,0,2,5">   

   4:                  <Image Width="15" Height="15" VerticalAlignment="Top" Source="{Binding Emotion, Converter={StaticResource EmotionToImageConverter}}" Margin="0,2,5,0"/>   

   5:                       <StackPanel Orientation="Vertical" Margin="2,0,2,5">   

   6:                         <TextBlock   

   7:                              TextWrapping="Wrap"   

   8:                              Text="{Binding StatusText}"   

   9:                              Width="400"  

  10:                              TextAlignment="Left"  

  11:                              Foreground="LightGray"/>  

  12:                              <TextBlock  

  13:                              Width="300"  

  14:                              HorizontalAlignment="Left"  

  15:                              TextAlignment="Left"  

  16:                              Text="{Binding Location}"  

  17:                              Foreground="DarkGray"/>  

  18:                          </StackPanel>  

  19:                      </StackPanel>  

  20:                </DataTemplate>  

  21:           </ListBox.ItemTemplate>  

  22:   </ListBox>

Although TwitterMonitor is a Model for our view, it doesn’t retrieve the data by itself, it uses IGeoLocationService and ITwitterMonitorService to do this.

TwitterMonitor’s main purpose is to put data from separate sources together and provide it to the TwitterMapViewModel.

Having data access code in separate assemblies allows us to reuse code in a better way.

The workflow looks as follows (click for bigger picture):

mvvm3

TwitterMonitorService in Wpf (blue) can call Api.Twitter directly, while Silverlight version (green) has to call local Wcf Service first due to cross-domain policy issues.

Unity Container inserts either blue or green version of TwitterMonitorService to TwitterMonitor depending on which framework is used.

Playground

You can download Emotwittion Solution here here.

Buy me a coffee to sponsor more posts like this!

Prism 2: WPF and Silverlight – Multi Platform Targeting

April 19th, 2009

prism

This post is part of a Prism 2 series:

Prism 2: WPF and Silverlight – Inversion of Control
Prism 2: WPF and Silverlight – Multi Platform Targeting
Prism 2: WPF and Silverlight – Modularity
Prism 2: WPF and Silverlight – Model-View-ViewModel
Prism 2: WPF and Silverlight – View Injection/View Discovery
Prism 2: WPF and Silverlight – Commands
Prism 2: WPF and Silverlight – Events
Prism 2: WPF and Silverlight – Services

In this post we’re going to focus on Multi-Platform Targeting.

As we know, WPF and Silverlight assemblies are not compatible. WPF compiles against full .NET framework while Silverlight uses it’s own .NET Framework subset.
But what if you want to share code between these two?
Well, there are few ways to accomplish this tasks. One would be to code against Silverlight and reference Silverlight assemblies in WPF project (in Visual Studio WPF project can reference Silverlight assemblies but Silverlight project cannot reference WPF).
Second option is to link files from two different projects together and recompile them separately and this is the solution that Prism 2 makes easier to manage.
Below is the list of few practices worth considering when writing multi-platform applications:

Project Linker Add-in

Prism 2 comes with Project Linker Add-in which we’re going to use to link two projects together.
Once projects are linked, all operations like creating/deleting/moving/copying file or directory will be mirrored in all linked project.
It can save us few clicks in small solutions and is a real must-have in bigger ones.
To link two projects together:
Click on a project and select ‘Add project link..‘ from context menu and select project you want to link to:

pl1

From now on two projects are linked and changes made to one will be reflected in the second one.
Now, if  we take a look into the project file, we will see new user setting:
<UserProperties ProjectLinkReference="c90b1fe8-b83b-4ca2-a149-5636d7ff7fd4" ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?silverlight(\\.*)?$;\.desktop;\.silverlight;\.xaml;^service references(\\.*)?$;\.clientconfig;^web references(\\.*)?$" />
ProjectLinkerExcludeFilter part is very interesting, it defines which changes to the project will be filtered out.
As we can see all files that contain .silverlight, .desktop or .clientconfig as well as services and web references will be skipped.

 

Common Namespace

It is important to remember that in most circumstances silverlight/wpf components should share the same namespace – this way code is fully portable.
One example of such situation is Shell and Bootstrapper classes from example attached below. Bootstrapper class and both Shell (from Wpf) and Shell (from Silverlight) belong to the same namespace.
Just remember that in Visual Studio, when you add new project it’s default namespace will be set to project’s name.
We may want to change it in project settings and remove last platform specific part (‘Wpf’ or ‘Silverlight)

 

Solution Structure
To keep solution more manageable we should keep it in structured form.
We can use hierarchy as in the picture below:

ps1

Prism 2 Guidance suggest to append project name with .Silverlight for SL projects or .Desktop / .DotNet for Wpf applications.
My personal opinion is that appending SL projects makes sense (to avoid duplicate names in solution), but doing so with other projects is an overkill.
I just assume that if project’s name doesn’t end with .Silverlight it targets full version of framework.

#if SILVERLIGHT precompiler directives
Sometimes, when it’s not possible to share code between Silverlight and WPF, we can use #if SILVERLIGHT construct to create conditionally compiled sections:

   1: #if SILVERLIGHT   

   2:      System.Windows.Application.Current.RootVisual = shell   

   3: #else   

   4:      Application.Current.MainWindow = shell;   

   5:      shell.Show();   

   6: #endif

By default, all Silverlight project have SILVERLIGHT defined as conditional compilation symbol.

The major drawback of this approach is that it greatly reduces code readablility and therefore should be used with care.

Partial Classes

As mentioned above using #if has few drawbacks. It makes code less readable and can break IntelliSense while debugging to name just a few.

It is often much better to use partial classes instead.

All we have to do is to move platform specific methods to partial classes and change extension of a new file to indicate it’s platform dependence:

prismpartial

Platform differences

It is important to know the differences between full Wpf and Silverlight, some of which are:

  • Supported Controls/Features – SL doesn’t support some controls out of the box. SL3 makes things little better and using this version will enable us to reuse more Xaml. One of other differences is usage of Triggers (Wpf) vs. ViewStates (Silverlight)
  • Xaml Processing Differences – there are few differences in how Xaml is processed between Wpf and Silverlight. Some are documented here, but there are few others (e.g. Silverlight doesn’t support {x:Static })

XAML Conditional Compilation

Chuck Jazdzewski wrote a great post about markup-compatibility (here).

He described how to write conditional Xaml code against WPF, so I decided to give it a try with multi-platform solution.

It seemed that using his approach we could write code like this:

   1: <Window   

   2:  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"   

   3:  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"   

   4:  xmlns:targetSilverlight="Silverlight"   

   5:  xmlns:targetWpf="Wpf">   

   6:  <mc:AlternateContent>   

   7:  <mc:Choice Requires="targetSilverlight">   

   8:  <Label>   

   9:  Some SL specific code here  

  10:  <Label>  

  11:  </mc:Choice>  

  12:  <mc:Choice Requires="targetWpf"><Label>Some Wpf specific code here..<Label></mc:Choice>  

  13:  <mc:AlternateContent>  

  14: </Window>

But unfortunately it doesn’t work..

As described in this document about Xaml processing differences between Wpf and Silverlight:

The only supported markup compatibility construct in Silverlight (from the XML namespace http://schemas.openxmlformats.org/markup-compatibility/2006, which is typically mapped to mc:) is mc:Ignorable.

It would be great to see it implemented in Silverlight 3, but for now we cannot use this method.

Playground

You can download Emotwittion Solution here.

Buy me a coffee to sponsor more posts like this!

Prism 2: WPF and Silverlight – Inversion of Control

April 18th, 2009

prism

This post is part of a Prism 2 series:

Prism 2: WPF and Silverlight – Inversion of Control
Prism 2: WPF and Silverlight – Multi Platform Targeting
Prism 2: WPF and Silverlight – Modularity
Prism 2: WPF and Silverlight – Model-View-ViewModel
Prism 2: WPF and Silverlight – View Injection/View Discovery
Prism 2: WPF and Silverlight – Commands
Prism 2: WPF and Silverlight – Events
Prism 2: WPF and Silverlight – Services

In next few post we’re going to have a closer look at Prism using Emotwittion as a reference application.
We’ll show how to create three different types of applications using minimum set of code modifications.
The applications that we will build are:

  • Emotwittion Silverlight Client
  • Emotwittion Desktop Client (Wpf)
  • Emotwittion ScreenSaver (Wpf)

Introduction
Prism 2 (known as Composite Application Guidance for WPF and Silverlight) is a guidance designed to help us more easily build modular WPF and SL client applications.
We can visit project’s website here: http://compositewpf.codeplex.com
Before we start exploring Prism’s world we have to be familiar with Inversion of Control (IoC) design pattern as it is going to be used very extensively.
Inversion Of Control (IoC)
Let’s imagine following scenario:
Our component (class) uses some services (other classes).
These services are declared and instantiated by our component, because it uses them (it controls them).
This approach feels very natural but it also brings few problems:

  • Tightly coupled elements – Our component has to know about concrete implementation of services at compile time
  • Manual and error prone update process – To replace the service, you have to update every component that uses it
  • Unit Testing – Components are difficult to test in isolation (services cannot be easily replaced with stubs/mocks)


Inversion of Control pattern is a great way to deal with issues mentioned above, and it comes in two flavors: Dependency Injection and Service Locator.

Dependency Injection
Instead of instantiating dependencies explicitly in our class, we can inject them when instance of the class is created.

depinjection

Our builder (object responsible for injecting services) exists in Prism in form of Unity Container.
We use Unity Container to register new types and resolve them at runtime.
Note that Prism doesn’t have to use Unity Container, you can easily replace it with any other framework.
Lets have a closer look at how Emotwittion uses this pattern.
After we receive Twitter Status and it’s Location, we have to map the location (e.g. London) to Longitude and Latitude so that we can position it on map.
To achieve this, Emotwittion uses GeoLocationService which queries Yahoo Geocoding API to get Longitude/Latitude values.
Yahoo API is not accessible from Silverlight due to cross-domain issues and this means that while desktop application can call it directly, Silverlight will have to call local web service first, and this webservice will in turn call Yahoo Geolocation API to avoid cross-domain issue.
Both Wpf and SL projects share IGeoLocationService interface, but the concrete implementations they use are very different.
Our TwitterMonitor (component) uses this IGeoLocationService interface to get longitude/latitude for the locations without knowing anything about concrete implementations of interface.
Instead, it expects concrete implementation of the service interface to be injected into the constructor:

   1: IGeoLocationService GeoLocationservice; 

   2: public TwitterMonitor(ITwitterMonitorService twitterMonitorService, IGeoLocationService geoLocationService, IEventAggregator eventAggregator) 

   3: { 

   4: this.GeoLocationservice = geoLocationService; 

   5: } 

The injection part happens when module is initialized.

First we register concrete implementation of IGeoLocationService:

   1: Container.RegisterInstance<IGeoLocationService>(new GeoLocationService());

Then we resolve TwitterMonitor using Container (IUnityContainer).

We registered GeoLocationService before, so now Container knows that every time IGeoLocationService interface is requested in a constructor of type being resolved, it should pass this registered concrete implementation to it.

   1: Container.Resolve<TwitterMonitor>(); 

So were do we get this Container from?

It’s been injected to our Module (in constructor, using the same technique) by Prism itself!

   1: public Module1(IUnityContainer container, IRegionManager regionManager) 

   2: { 

   3:     this.Container = container; 

   4:     this.RegionManager = regionManager; 

   5: } 

Key thing to remember using Dependency Injection pattern is that every component have to be resolved by the container (and not created using new keyword).

Service Locator

Another approach to IoC is Service Locator.

Service Locator works with connection to Container (Unity Container by default) and can be used to get services from within the component.

servicelocator

Let’s get back to TwitterMonitor class for a moment.

We’ve already seen that it has constructor that expects services as parameters (which is used for Dependency Injection), but lets have a look now at the default constructor:

   1: public TwitterMonitor() 

   2: { 

   3: this.TwitterMonitorService = ServiceLocator.Current.GetInstance<ITwitterMonitorService>(); 

   4: this.GeoLocationservice = ServiceLocator.Current.GetInstance<IGeoLocationService>(); 

   5: this.EventAggregator = ServiceLocator.Current.GetInstance<IEventAggregator>(); 

   6:             Initialize(); 

   7: } 

As we can see, default constructor uses static property Current to get current ServiceLocator and calls GetInstance() method on it to get the instance of IGeoLocationService.

Where does this instance come from?

It work’s the same way as in case of Dependency Injection – it’s registered in Initialize() method of the module:

   1: Container.RegisterInstance<IGeoLocationService>(new GeoLocationService()); 

This way TwitterMonitor can be initialized in two ways, using Container and Dependency Injection:

   1: var twitterMonitor = Container.Resolve<TwitterMonitor>(); 

or simply by creating new instance with help of Service Locator:

   1: var twitterMonitor = new TwitterMonitor(); 

In Prism, ServiceLocator uses Unity Adapter by default.

Adapters for other containers exist (Castle Windsor, Autofac, Spring .Net) and can be found on the project website here.


Service Locator vs Dependency Injection

The key difference between the two is that with Service Locator every component has a dependency to the locator, but other dependencies (to services) are hidden from the caller.

With Dependency Injection, components depend only on interfaces of services they want to use, but it’s the caller’s responsibility to ensure that these dependencies are injected to components using containers like Unity.

I personally prefer to use mix of both (default and overloaded constructor) for code that is going to be used within the company.

In cases when API is going to be used by other people and dependence to the locator is not an option I’d use Dependency Injection only.

I wouldn’t use Service Locator exclusively because it hides service dependencies from the caller and creates discovery/maintenance issues.

Once we have a constructor that expects all services as parameters, API users can use it without any knowledge about IoC pattern. In the worst case scenario they’re just going to provide concrete service implementations manually to the constructor.


Exploring Prism – where to start

If you are new to Prism, you may want to start having a look from App.xaml files as Bootstrappers are initialized there (Bootstrapper is the entry point for Prism 2).

In Wpf we override OnStartup() method of Application:

   1: public partial class App : Application 

   2: { 

   3:     protected override void OnStartup(StartupEventArgs e) 

   4:       { 

   5:         base.OnStartup(e); 

   6:         Bootstrapper bootStrapper = new Bootstrapper(); 

   7:         bootStrapper.Run(); 

   8:       } 

   9: } 

In Silverlight we have to modify Application_Startup method (which handles Application.Startup event):

   1: private void Application_Startup(object sender, StartupEventArgs e) 

   2: { 

   3: Bootstrapper bootstrapper = new Bootstrapper(); 

   4:          bootstrapper.Run(); 

   5: } 

That’s all for today, in the next post we’ll have a look at modularity and how it can benefit us.

Playground

You can download Emotwittion Solution here here.

Buy me a coffee to sponsor more posts like this!

Prism and WPF Browser Application (Xbap)

September 29th, 2008

For next few weeks I’m going to evaluate usage of Composite WPF (codename PRISM) with my next project.

One of the first things I want to check is whether it’s possible to use Prism with WPF Browser Application.
Short answer is: yes.
Long answer is: yes, but some preparation is needed.

First of all, we want our application to be partially trusted to make deployment easier.
This means that Prism assemblies should allow partially trusted callers. Adding following line in Prism’s assemblyinfo.cs will do the trick:

   1: [assembly: AllowPartiallyTrustedCallers]

Second, our bootstrapper has to return some sort of shell in a CreateShell() method (so that it can be registered with RegionManager) . For desktop application we would probably create instance of bootstrapper in Application class and have it return new Window that would be used as a shell.

In our case Application object creates new Page using StartupUri property and only after Page is created we have access to it, so Page’s constructor seems like a perfect place to run bootstrapper from:

   1: public partial class Client : Page   

   2: {   

   3:      public Client()   

   4:      {   

   5:         BootStrapper bootStrapper = new BootStrapper();   

   6:  

   7:         bootStrapper.ShellPage = this;   

   8:         bootStrapper.Run();   

   9:      

  10:         InitializeComponent();   

  11:      }  

  12: }

And the bootstrapper code:

   1: class BootStrapper : UnityBootstrapper   

   2: {   

   3:     private DependencyObject shellPage;    

   4:     

   5:     public DependencyObject ShellPage   

   6:     {   

   7:         get   

   8:         {   

   9:             return shellPage;  

  10:         }   

  11:         

  12:         set  

  13:         {  

  14:             shellPage = value;  

  15:         }  

  16:     }   

  17:     

  18:     protected override Microsoft.Practices.Composite.Modularity.IModuleEnumerator GetModuleEnumerator()  

  19:     {  

  20:         StaticModuleEnumerator enumerator = new StaticModuleEnumerator();   

  21:         

  22:         enumerator.AddModule(typeof(MyModule), null);   

  23:         

  24:         return enumerator;  

  25:     }   

  26:     

  27:     protected override System.Windows.DependencyObject CreateShell()  

  28:     {  

  29:         return ShellPage;  

  30:     }

  31: }

In my case there was one more little thing I had to do which I think is worth mentioning.

I was porting my existing desktop application to xbap and left some debugging code which caused runtime error.

Apparently you cannot use AppDomain.UnhandledException event in xbap application so I had to remove following line from code:

   1: AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

UPDATE: 20/04/2009

In code above we override GetModuleEnumerator() method to get static list of modules.

This method no longer exists in Prism 2, and we should write this instead:

   1: protected override IModuleCatalog GetModuleCatalog()   

   2: {   

   3:     ModuleCatalog moduleCatalog = new ModuleCatalog();   

   4:     

   5:     moduleCatalog.AddModule(typeof(MyModule));   

   6:     

   7:     return moduleCatalog;   

   8: }

Buy me a coffee to sponsor more posts like this!