Prism Event Aggregator in WPF With MVVM

This article shows how to publish events and how to subscribe to them using WPF MVVM and PRISM.

EventAggregator

Components in a composite application often need to communicate with other components and services in the application in a loosely coupled way. To support this, Prism provides the EventAggregator component that implements a pub-sub event mechanism, thereby allowing components to publish events and other components to subscribe to those events without either of them requiring a reference to the other. The EventAggregator is often used to allow components defined in different modules to communicate with each other.



PubSubEvent

Connecting publishers and subscribers is done by the PubSubEvent class. This is the only implementation of the EventBase class that is included in the Prism Library. This class maintains the list of subscribers and handles event dispatching to the subscribers.

Event Publishing

Publishers raise an event by retrieving the event from the EventAggregator and calling the Publish method. To access the EventAggregator, you can use dependency injection by adding a parameter of type IEventAggregator to the class constructor.

That is shown in the following code.

  1. public Person SelectedPerson 
  2. {   
  3.     get  
  4.     {   
  5.         return this.selectedPerson;   
  6.     }  
  7.     set  
  8.     {   
  9.         if(this.selectedPerson!=value)  
  10.         {   
  11.             this.selectedPerson = value;  
  12.             this.NotifyPropertyChanged("SelectedPerson");  
  13.               
  14.             // Publish event.  
  15.             this  
  16. .iEventAggregator  
  17. .GetEvent<PubSubEvent<Person>>()  
  18. .Publish(this.SelectedPerson);  
  19.         }  
  20.     }  
  21. }  
Here I have taken the property “SelectedPerson” and with the property setter I have published an event.

Event Subscribing

Subscribers can enlist with an event using one of the Subscribe method overloads available on the PubSubEvent class.

That is shown in the following code.
  1. SubscriptionToken subscriptionToken =  
  2.       
  3. this                                    .iEventAggregator                             
  4.     .GetEvent<PubSubEvent<Person>>()                          
  5.         .Subscribe((details) =>  
  6.     {       this.Person = details;        
  7.     });  
Here I have taken the property “Person” and initialized the published event parameter to person.

Note: Here we need to use both the publisher and subscriber types as the same.

Event Unsubscribing

If your subscriber no longer wants to receive events, you can unsubscribe using your subscriber's handler or you can unsubscribe using a subscription token.

That is shown in the following code.
  1. this  
  2.     .iEventAggregator  
  3.     .GetEvent<PubSubEvent<Person>>()  
  4.     .Unsubscribe(subscriptionToken);      
Here I have unsubscribed using the subscriber's “subscriptionToken”.

Sample Code

Folder Structure: See the screen below.



In view

Provide the following code for Person1.xaml.
  1. <UserControl x:Class="PrismEventAggregator.Views.Person1"  
  2.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
  3.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
  4.              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
  5.              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
  6.              BorderBrush="Black"  
  7.              BorderThickness="2"  
  8.              d:DesignHeight="300"  
  9.              d:DesignWidth="300"  
  10.              mc:Ignorable="d">  
  11.     <Grid Margin="10 10 0 0">  
  12.         <DataGrid AutoGenerateColumns="False"  
  13.                   CanUserAddRows="False"  
  14.                   ItemsSource="{Binding PersonDetails}"  
  15.                   SelectedItem="{Binding SelectedPerson}">  
  16.             <DataGrid.Columns>  
  17.                 <DataGridTemplateColumn Header="Id">  
  18.                     <DataGridTemplateColumn.CellTemplate>  
  19.                         <DataTemplate>  
  20.                             <TextBlock Text="{Binding Id}" />  
  21.                         </DataTemplate>  
  22.                     </DataGridTemplateColumn.CellTemplate>  
  23.                 </DataGridTemplateColumn>  
  24.                 <DataGridTemplateColumn Header="Name">  
  25.                     <DataGridTemplateColumn.CellTemplate>  
  26.                         <DataTemplate>  
  27.                             <TextBlock Text="{Binding Name}" />  
  28.                         </DataTemplate>  
  29.                     </DataGridTemplateColumn.CellTemplate>  
  30.                 </DataGridTemplateColumn>  
  31.                 <DataGridTemplateColumn Header="Address">  
  32.                     <DataGridTemplateColumn.CellTemplate>  
  33.                         <DataTemplate>  
  34.                             <TextBlock Text="{Binding Address}" />  
  35.                         </DataTemplate>  
  36.                     </DataGridTemplateColumn.CellTemplate>  
  37.                 </DataGridTemplateColumn>  
  38.             </DataGrid.Columns>  
  39.         </DataGrid>  
  40.     </Grid>  
  41. </UserControl>  
Provide the following code for Person1.xaml.cs.
  1. /// <summary>  
  2. /// Interaction logic for Person1.xaml  
  3. /// </summary>  
  4. public partial class Person1 : UserControl  
  5. {  
  6.     public Person1()  
  7.     {  
  8.         InitializeComponent();  
  9.         this.DataContext = new Person1ViewModel(Event.EventInstance.EventAggregator);  
  10.     }  
  11. }  
Provide the following code for Person2.xaml.
  1. <UserControl x:Class="PrismEventAggregator.Views.Person2"  
  2.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
  3.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
  4.              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
  5.              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
  6.              BorderBrush="Black"  
  7.              BorderThickness="2"  
  8.              d:DesignHeight="300"  
  9.              d:DesignWidth="300"  
  10.              mc:Ignorable="d">  
  11.     <Grid Margin="10 10 0 0">  
  12.         <DataGrid AutoGenerateColumns="False"  
  13.                   CanUserAddRows="False"  
  14.                   ItemsSource="{Binding PersonDetails}"  
  15.                   SelectedItem="{Binding SelectedPerson}">  
  16.             <DataGrid.Columns>  
  17.                 <DataGridTemplateColumn Header="Id">  
  18.                     <DataGridTemplateColumn.CellTemplate>  
  19.                         <DataTemplate>  
  20.                             <TextBlock Text="{Binding Id}" />  
  21.                         </DataTemplate>  
  22.                     </DataGridTemplateColumn.CellTemplate>  
  23.                 </DataGridTemplateColumn>  
  24.                 <DataGridTemplateColumn Header="Name">  
  25.                     <DataGridTemplateColumn.CellTemplate>  
  26.                         <DataTemplate>  
  27.                             <TextBlock Text="{Binding Name}" />  
  28.                         </DataTemplate>  
  29.                     </DataGridTemplateColumn.CellTemplate>  
  30.                 </DataGridTemplateColumn>  
  31.                 <DataGridTemplateColumn Header="Address">  
  32.                     <DataGridTemplateColumn.CellTemplate>  
  33.                         <DataTemplate>  
  34.                             <TextBlock Text="{Binding Address}" />  
  35.                         </DataTemplate>  
  36.                     </DataGridTemplateColumn.CellTemplate>  
  37.                 </DataGridTemplateColumn>  
  38.             </DataGrid.Columns>  
  39.         </DataGrid>  
  40.     </Grid>  
  41. </UserControl>  
Provide the following code for Person2.xaml.cs.
  1. /// <summary>  
  2. /// Interaction logic for Person2.xaml  
  3. /// </summary>  
  4. public partial class Person2 : UserControl  
  5. {  
  6.     public Person2()  
  7.     {  
  8.         InitializeComponent();  
  9.         this.DataContext = new Person2ViewModel(Event.EventInstance.EventAggregator);  
  10.     }  
  11.  
Provide the following code for PersonDetails1.xaml.
  1. <UserControl x:Class="PrismEventAggregator.Views.PersonDetails1"  
  2.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
  3.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
  4.              Width="200"  
  5.              Height="250"  
  6.              BorderBrush="Black"  
  7.              BorderThickness="2">  
  8.     <Grid>  
  9.         <Grid.RowDefinitions>  
  10.             <RowDefinition Height="25" />  
  11.             <RowDefinition Height="*" />  
  12.         </Grid.RowDefinitions>  
  13.         <Button Width="80"  
  14.                 Height="25"  
  15.                 Margin="10,0,106,0"  
  16.                 Command="{Binding Subscribe}"  
  17.                 Content="Subscribe" />  
  18.         <Button Width="80"  
  19.                 Height="25"  
  20.                 Margin="106,0,10,0"  
  21.                 Command="{Binding Unsubscribe}"  
  22.                 Content="Unsubscribe" />  
  23.         <ContentControl Grid.Row="1" Content="{Binding Person}">  
  24.             <ContentControl.ContentTemplate>  
  25.                 <DataTemplate>  
  26.                     <Grid>  
  27.                         <Grid.RowDefinitions>  
  28.                             <RowDefinition Height="auto" />  
  29.                             <RowDefinition Height="auto" />  
  30.                             <RowDefinition Height="auto" />  
  31.                             <RowDefinition Height="auto" />  
  32.                             <RowDefinition Height="auto" />  
  33.                             <RowDefinition Height="auto" />  
  34.                             <RowDefinition Height="auto" />  
  35.                             <RowDefinition Height="auto" />  
  36.                             <RowDefinition Height="auto" />  
  37.                             <RowDefinition Height="auto" />  
  38.                             <RowDefinition Height="*" />  
  39.                         </Grid.RowDefinitions>  
  40.                         <TextBlock Grid.Row="0"  
  41.                                    Grid.RowSpan="2"  
  42.                                    Text="Person Details" />  
  43.                         <TextBlock Grid.Row="2" Text="Id: " />  
  44.                         <TextBlock Grid.Row="3" Text="{Binding Id}" />  
  45.                         <TextBlock Grid.Row="4" Text="Name: " />  
  46.                         <TextBlock Grid.Row="5" Text="{Binding Name}" />  
  47.                         <TextBlock Grid.Row="6" Text="Address: " />  
  48.                         <TextBlock Grid.Row="7" Text="{Binding Address}" />  
  49.                         <TextBlock Grid.Row="8" Text="Photo" />  
  50.                         <Image Grid.Row="8" Source="{Binding Photo}" />  
  51.                     </Grid>  
  52.                 </DataTemplate>  
  53.             </ContentControl.ContentTemplate>  
  54.         </ContentControl>  
  55.     </Grid>  
  56. </UserControl>  
Provide the following code for PersonDetails1.xaml.cs.
  1. /// <summary>  
  2. /// Interaction logic for PersonDetails1.xaml  
  3. /// </summary>  
  4. public partial class PersonDetails1 : UserControl  
  5. {  
  6.     public PersonDetails1()  
  7.     {  
  8.         InitializeComponent();  
  9.         this.DataContext = new  PersonDetails1ViewModel(Event.EventInstance.EventAggregator);  
  10.     }  
  11.  
Provide the following code for PersonDetails2.xaml.
  1. <UserControl x:Class="PrismEventAggregator.Views.PersonDetails2"  
  2.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
  3.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
  4.              Width="200"  
  5.              Height="250"  
  6.              BorderBrush="Black"  
  7.              BorderThickness="2">  
  8.     <Grid Margin="10">  
  9.         <ContentControl Content="{Binding Person}">  
  10.             <ContentControl.ContentTemplate>  
  11.                 <DataTemplate>  
  12.                     <Grid>  
  13.                         <Grid.RowDefinitions>  
  14.                             <RowDefinition Height="auto" />  
  15.                             <RowDefinition Height="auto" />  
  16.                             <RowDefinition Height="auto" />  
  17.                             <RowDefinition Height="auto" />  
  18.                             <RowDefinition Height="auto" />  
  19.                             <RowDefinition Height="auto" />  
  20.                             <RowDefinition Height="auto" />  
  21.                             <RowDefinition Height="auto" />  
  22.                             <RowDefinition Height="auto" />  
  23.                             <RowDefinition Height="auto" />  
  24.                             <RowDefinition Height="*" />  
  25.                         </Grid.RowDefinitions>  
  26.                         <TextBlock Grid.Row="0"  
  27.                                    Grid.RowSpan="2"  
  28.                                    Text="Person Details" />  
  29.                         <TextBlock Grid.Row="2" Text="Id: " />  
  30.                         <TextBlock Grid.Row="3" Text="{Binding Id}" />  
  31.                         <TextBlock Grid.Row="4" Text="Name: " />  
  32.                         <TextBlock Grid.Row="5" Text="{Binding Name}" />  
  33.                         <TextBlock Grid.Row="6" Text="Address: " />  
  34.                         <TextBlock Grid.Row="7" Text="{Binding Address}" />  
  35.                         <TextBlock Grid.Row="8" Text="Photo" />  
  36.                         <Image Grid.Row="8" Source="{Binding Photo}" />  
  37.                     </Grid>  
  38.                 </DataTemplate>  
  39.             </ContentControl.ContentTemplate>  
  40.         </ContentControl>  
  41.     </Grid>  
  42. </UserControl>  
Provide the following code for PersonDetails2.xaml.cs.
  1. /// <summary>  
  2. /// Interaction logic for PersonDetails2.xaml  
  3. /// </summary>  
  4. public partial class PersonDetails2 : UserControl  
  5. {  
  6.     public PersonDetails2()  
  7.     {  
  8.         InitializeComponent();  
  9.         this.DataContext = new PersonDetails2ViewModel(Event.EventInstance.EventAggregator);  
  10.     }  
  11.  
In ViewModel

Provide the following code for Person1ViewModel.cs. 
  1. public class Person1ViewModel : INotifyPropertyChanged  
  2. {  
  3.    
  4.         #region Instance Properties  
  5.    
  6.     public List<Person> PersonDetails   
  7.     {     
  8.         get  
  9.         {   
  10.             return this.personDetails;  
  11.         }  
  12.         set  
  13.         {   
  14.             if(this.personDetails != value)  
  15.             {   
  16.                 this.personDetails = value;  
  17.                 this.NotifyPropertyChanged("PersonDetails");  
  18.             }  
  19.         }  
  20.     }  
  21.    
  22.     public Person SelectedPerson {   
  23.         get  
  24.         {   
  25.             return this.selectedPerson;   
  26.         }  
  27.         set  
  28.         {   
  29.             if(this.selectedPerson!=value)  
  30.             {   
  31.                 this.selectedPerson = value;  
  32.                 this.NotifyPropertyChanged("SelectedPerson");  
  33.    
  34.                 // Publish event.  
  35.                 this  
  36.                     .iEventAggregator  
  37.                     .GetEvent<PubSubEvent<Person>>()  
  38.                     .Publish(this.SelectedPerson);  
  39.             }  
  40.         }  
  41.     }  
  42.    
  43.         #endregion  
  44.    
  45.         #region Constructors  
  46.    
  47.     public Person1ViewModel(IEventAggregator iEventAggregator)  
  48.     {   
  49.         this.iEventAggregator = iEventAggregator;  
  50.         this.PersonDetails = new List<Person>();  
  51.         this.PersonDetails.Add(new Person() { Address = "Hyderabad"Name = "Hari"Id = 1Photo = "/PrismEventAggregator;component/Resources/Images/img_chania.jpg" });  
  52.         this.PersonDetails.Add(new Person() { Address = "Guntur"Name = "Murali"Id = 2Photo = "/PrismEventAggregator;component/Resources/Images/img_chania2.jpg" });  
  53.         this.PersonDetails.Add(new Person() { Address = "Ongole"Name = "Varun"Id = 3Photo = "/PrismEventAggregator;component/Resources/Images/img_flower2.jpg" });  
  54.     }  
  55.    
  56.         #endregion  
  57.    
  58.         #region INotifyPropertyChanged Implementation  
  59.    
  60.     public event PropertyChangedEventHandler PropertyChanged;  
  61.    
  62.     protected void NotifyPropertyChanged([CallerMemberName] string propertyName = "")  
  63.     {  
  64.         if (PropertyChanged != null)  
  65.         {  
  66.             PropertyChanged(this, new PropertyChangedEventArgs(propertyName));  
  67.         }  
  68.     }  
  69.    
  70.         #endregion  
  71.    
  72.         #region Instance Fields  
  73.    
  74.     private List<Person> personDetails;  
  75.    
  76.     private Person selectedPerson;  
  77.    
  78.     private IEventAggregator iEventAggregator;  
  79.    
  80.         #endregion  
  81.    
  82. }  
Provide the following code for Person2ViewModel.cs.
  1. public class Person2ViewModel : INotifyPropertyChanged  
  2. {  
  3.   
  4.         #region Instance Properties  
  5.    
  6.     public List<Person> PersonDetails  
  7.     {  
  8.         get  
  9.         {  
  10.             return this.personDetails;  
  11.         }  
  12.         set  
  13.         {  
  14.             if (this.personDetails != value)  
  15.             {  
  16.                 this.personDetails = value;  
  17.                 this.NotifyPropertyChanged("PersonDetails");  
  18.             }  
  19.         }  
  20.     }  
  21.    
  22.     public Person SelectedPerson  
  23.     {  
  24.         get  
  25.         {  
  26.             return this.selectedPerson;  
  27.         }  
  28.         set  
  29.         {  
  30.             if (this.selectedPerson != value)  
  31.             {  
  32.                 this.selectedPerson = value;  
  33.                 this.NotifyPropertyChanged("SelectedPerson");  
  34.                 this  
  35.                     .iEventAggregator  
  36.                     .GetEvent<PubSubEvent<Person>>()  
  37.                     .Publish(this.SelectedPerson);  
  38.             }  
  39.         }  
  40.     }  
  41.   
  42.         #endregion  
  43.   
  44.         #region Constructors  
  45.    
  46.     public Person2ViewModel(IEventAggregator iEventAggregator)  
  47.     {  
  48.         this.iEventAggregator = iEventAggregator;  
  49.         this.PersonDetails = new List<Person>();  
  50.         this.PersonDetails.Add(new Person() { Address = "Vizag", Name = "Pavan", Id = 1, Photo = "/PrismEventAggregator;component/Resources/Images/img1.jpg" });  
  51.         this.PersonDetails.Add(new Person() { Address = "Vijayawada", Name = "Mahesh", Id = 2, Photo = "/PrismEventAggregator;component/Resources/Images/img2.jpg" });  
  52.         this.PersonDetails.Add(new Person() { Address = "Nellore", Name = "Srinivas", Id = 3, Photo = "/PrismEventAggregator;component/Resources/Images/img3.jpg" });  
  53.     }  
  54.   
  55.         #endregion  
  56.   
  57.         #region INotifyPropertyChanged Implementation  
  58.    
  59.     public event PropertyChangedEventHandler PropertyChanged;  
  60.    
  61.     protected void NotifyPropertyChanged([CallerMemberName] string propertyName = "")  
  62.     {  
  63.         if (PropertyChanged != null)  
  64.         {  
  65.             PropertyChanged(thisnew PropertyChangedEventArgs(propertyName));  
  66.         }  
  67.     }  
  68.   
  69.         #endregion  
  70.   
  71.         #region Instance Fields  
  72.    
  73.     private List<Person> personDetails;  
  74.    
  75.     private Person selectedPerson;  
  76.    
  77.     private IEventAggregator iEventAggregator;  
  78.   
  79.         #endregion  
  80.    
  81. }  
Provide the following code for PersonDetails1ViewModel.cs.
  1. public class PersonDetails1ViewModel: INotifyPropertyChanged  
  2. {  
  3.   
  4.         #region Instance Properties  
  5.    
  6.     public Person Person {  
  7.           
  8.         get  
  9.         {   
  10.             return this.persionDetails;  
  11.         }     
  12.         set  
  13.         {   
  14.             if(this.persionDetails!=value)  
  15.             {   
  16.                 this.persionDetails = value;  
  17.                 this.NotifyPropertyChanged("Person");  
  18.             }  
  19.         }  
  20.       
  21.     }  
  22.    
  23.     public ICommand Unsubscribe { getset; }  
  24.    
  25.     public ICommand Subscribe { getset; }  
  26.   
  27.         #endregion  
  28.   
  29.         #region Constructors  
  30.    
  31.     public PersonDetails1ViewModel(IEventAggregator iEventAggregator)  
  32.     {   
  33.         this.iEventAggregator = iEventAggregator;  
  34.         SubscriptionToken subscriptionToken =  
  35.                                 this  
  36.                                     .iEventAggregator  
  37.                                     .GetEvent<PubSubEvent<Person>>()  
  38.                                     .Subscribe((details) =>  
  39.                                     {  
  40.                                         this.Person = details;  
  41.                                     });  
  42.    
  43.         this.Subscribe = new DelegateCommand(  
  44.         () =>  
  45.         {  
  46.             subscriptionToken =  
  47.                 this  
  48.                     .iEventAggregator  
  49.                     .GetEvent<PubSubEvent<Person>>()  
  50.                     .Subscribe((details) =>  
  51.                     {  
  52.                         this.Person = details;  
  53.                     });  
  54.         });  
  55.    
  56.         this.Unsubscribe = new DelegateCommand(  
  57.             () => {  
  58.    
  59.                 this  
  60.                     .iEventAggregator  
  61.                     .GetEvent<PubSubEvent<Person>>()  
  62.                     .Unsubscribe(subscriptionToken);          
  63.             });  
  64.     }  
  65.   
  66.         #endregion  
  67.   
  68.         #region INotifyPropertyChanged Implementation  
  69.    
  70.     public event PropertyChangedEventHandler PropertyChanged;  
  71.    
  72.     protected void NotifyPropertyChanged([CallerMemberName] string propertyName = "")  
  73.     {  
  74.         if (PropertyChanged != null)  
  75.         {  
  76.             PropertyChanged(thisnew PropertyChangedEventArgs(propertyName));  
  77.         }  
  78.     }  
  79.   
  80.         #endregion  
  81.   
  82.         #region Instance Fields  
  83.    
  84.     private Person persionDetails;  
  85.    
  86.     private IEventAggregator iEventAggregator;  
  87.   
  88.         #endregion  
  89. }  
Provide the following code for PersonDetails2ViewModel.cs.
  1. public class PersonDetails2ViewModel : INotifyPropertyChanged  
  2.     {  
  3.   
  4.         #region Instance Properties  
  5.    
  6.         public Person Person  
  7.         {  
  8.    
  9.             get  
  10.             {  
  11.                 return this.persionDetails;  
  12.             }  
  13.             set  
  14.             {  
  15.                 if (this.persionDetails != value)  
  16.                 {  
  17.                     this.persionDetails = value;  
  18.                     this.NotifyPropertyChanged("Person");  
  19.                 }  
  20.             }  
  21.    
  22.         }  
  23.   
  24.         #endregion  
  25.   
  26.         #region Constructors  
  27.    
  28.         public PersonDetails2ViewModel(IEventAggregator iEventAggregator)  
  29.         {  
  30.             this.iEventAggregator = iEventAggregator;  
  31.             this  
  32.                 .iEventAggregator  
  33.                 .GetEvent<PubSubEvent<Person>>()  
  34.                 .Subscribe((details) =>  
  35.                 {  
  36.                     this.Person = details;  
  37.                 });  
  38.         }  
  39.   
  40.         #endregion  
  41.   
  42.         #region INotifyPropertyChanged Implementation  
  43.    
  44.         public event PropertyChangedEventHandler PropertyChanged;  
  45.    
  46.         protected void NotifyPropertyChanged([CallerMemberName] string propertyName = "")  
  47.         {  
  48.             if (PropertyChanged != null)  
  49.             {  
  50.                 PropertyChanged(thisnew PropertyChangedEventArgs(propertyName));  
  51.             }  
  52.         }  
  53.   
  54.         #endregion  
  55.   
  56.         #region Instance Fields  
  57.    
  58.         private Person persionDetails;  
  59.    
  60.         private IEventAggregator iEventAggregator;  
  61.   
  62.         #endregion  
  63.     }  
In Model
 
Provide the following code for Event.cs.
  1. public sealed class Event  
  2. {  
  3.         #region Class Properties  
  4.    
  5.     internal static Event EventInstance  
  6.     {  
  7.         get  
  8.         {  
  9.             return eventInstance;  
  10.         }  
  11.     }  
  12.   
  13.         #endregion  
  14.   
  15.         #region Instance Properties  
  16.    
  17.     internal IEventAggregator EventAggregator  
  18.     {  
  19.         get  
  20.         {  
  21.             if (eventAggregator == null)  
  22.             {  
  23.                 eventAggregator = new EventAggregator();  
  24.             }  
  25.    
  26.             return eventAggregator;  
  27.         }  
  28.     }  
  29.   
  30.         #endregion  
  31.   
  32.         #region Constructors  
  33.    
  34.     private Event()  
  35.     {  
  36.           
  37.     }  
  38.   
  39.         #endregion  
  40.   
  41.         #region Class Fields  
  42.    
  43.     private static readonly Event eventInstance = new Event();  
  44.   
  45.         #endregion  
  46.   
  47.         #region Instance Fields  
  48.    
  49.     private IEventAggregator eventAggregator;  
  50.   
  51.         #endregion  
  52.    
  53. }  
  54.   
  55. Provide the following code for Person.cs.  
  56.   
  57. public class Person  
  58. {  
  59.   
  60.         #region Instance Properties  
  61.    
  62.     public int Id { getset; }  
  63.    
  64.     public string Name { getset; }  
  65.    
  66.     public string Photo { getset; }  
  67.    
  68.     public string Address { getset; }  
  69.   
  70.         #endregion  
  71.    
  72. }  
See the Final Screen Shot