New Home..
I’m migrating my blog over to here.
Head over there, there will be more code sample available there.
Getting started with Silverlight and MEF, Import and Export
For this example, I am using Silverlight 3 and the appropriate version of MEF. The example works in Silverlight 4 as well.
The first thing to do is create a new Silverlight application project. I called mine MEFDemo and didnt select the option to create a new website. I then added two new Silverlight controls, Control1 and Control2.
I also modified the MainPage control, here is the xaml.
<UserControl x:Class="MEFDemo.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid x:Name="LayoutRoot"> <StackPanel Orientation="Vertical"> <StackPanel Name="Top"> </StackPanel> <StackPanel Name="Main"> </StackPanel> </StackPanel> </Grid> </UserControl>
I defined StackPanels called Top and Main, these represent areas that we can add controls into later on.
I then added a reference to System.ComponentModel.Composition and System.ComponentModel.Compisition.Initialization.
I then added a new item called Location.cs with the following code.
namespace MEFDemo { public enum Location { Top, Main } }
This is going to be used so that we can configure our controls to appear in a place holder. We are going to use this by defining meta data on our control. We need to define an interface for this meta data, so that MEF can dynamically generate a proxy for us. The interface I have looks like so.
namespace MEFDemo { public interface IMefMetaData { Location Location { get; } } }
The next thing to do is change our MainPage control to get a collection of controls using the [ImportMany] attribute. The code for MainPage looks like so.
using System; using System.ComponentModel.Composition; using System.Windows.Controls; namespace MEFDemo { public partial class MainPage : UserControl { [ImportMany] public Lazy<UserControl, IMefMetaData>[] Controls { get; set; } public MainPage() { InitializeComponent(); PartInitializer.SatisfyImports(this); foreach (var control in Controls) { if(control.Metadata.Location == Location.Top) Top.Children.Add(control.Value); if (control.Metadata.Location == Location.Main) Main.Children.Add(control.Value); } } } }
Here we get a list of Controls, call the SatisfyImports method on the PartInitializer and then use our meta data to decide where to add the control.
In order to configure our 2 controls to get picked up by the [ImportMany] attribute we need change their code a little, the example for each is below.
Control1
using System.ComponentModel.Composition; using System.Windows.Controls; namespace MEFDemo { [Export(typeof(UserControl))] [ExportMetadata("Location", Location.Top)] public partial class Control1 : UserControl { public Control1() { InitializeComponent(); } } }
Control2
using System.ComponentModel.Composition; using System.Windows.Controls; namespace MEFDemo { [Export(typeof(UserControl))] [ExportMetadata("Location", Location.Main)] public partial class Control2 : UserControl { public Control2() { InitializeComponent(); } } }
In control 1 we configure the Location property on the meta data to Top, and in control 2 we configure it to Main. If we run this, control 1 will load above control 2. If it doesnt, then my explanation was rubbish and you should go download the code.
Obviously you can be clever with this, you could use Linq on the list of Controls, and filter them based on User Roles or preferences.
RIA Services Examples – Using InvokeOperation
I’m going to start a list of RIA services examples, keeping them short and sweet.
This one shows how to call a method that returns a Boolean and use InvokeOperation.
Consider the following RIA service.
public class AuthenticationService : DomainService { private readonly IApplicationConfigurationService _appConfigService; private readonly IAuthenticationService _authService; public AuthenticationService() { _appConfigService = With.IoC.GetService<IApplicationConfigurationService>(); _authService = With.IoC.GetService<IAuthenticationService>(); } public Boolean Authenticate(String email, String password) { var user = With.IoC.GetService<IUser>(); user.EmailAddress = email; user.Password = password.Encrypt(_appConfigService.FindByGroupAndKey( ApplicationConfigurationGroups.CommonEncryption.ToString(), ApplicationConfigurationKeys.CommonEncryptionKey.ToString() ) .Value); return _authService.Authenticate(user); } }
You can call the Authenticate method in a Silverlight application like so, using a delegate to capture the InvokeOperation
private readonly AuthenticationContext _authContext = new AuthenticationContext(); _authContext.Authenticate( Username.Text, Password.Password, delegate(InvokeOperation<Boolean> inv) { IsAuthenticated = inv.Value; //do something else }, null);
Entity framework profiler beta
I’ve been using NHProf since the beta now, and its become a pretty vital tool to me.
Its great that Ayende has been working on an Entity Framework version, this has just made public beta. If you use Entity Framework then you should really check it out.
Dynamically loading controls in Silverlight
Recently I found myself wanting to specify at ‘start up’ time which Control loaded by default in a Silverlight application. For those of you that dont know, you can pass initParams into the Silverlight application that are available at Application Start.
An example of this could be like.
<div id="silverlightControlHost"> <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%"> <param name="source" value="ClientBin/EMASolutions.CMS.Plugins.Silverlight.xap"/> <param name="onError" value="onSilverlightError" /> <param name="background" value="white" /> <param name="minRuntimeVersion" value="3.0.40818.0" /> <param name="autoUpgrade" value="true" /> <param name="initParams" value="firstControl=EMASolutions.CMS.Plugins.Silverlight.FolderBrowser" /> <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=3.0.40818.0" style="text-decoration:none"> <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style:none"/> </a> </object> <iframe id="_sl_historyFrame" style="visibility:hidden;height:0px;width:0px;border:0px"></iframe> </div>
The initParams take the following format, key=value,key1=value1. Notice in this example we passover the fully qualified type name of the control to load on Application Start. This is a simple example, in reality the type name would be driven from user actions and would probably be a persisted value rather than a ‘magic string’.
Anyway, we can access our ‘firstControl’ value like so.
private void Application_Startup(object sender, StartupEventArgs e) { if (!NetworkInterface.GetIsNetworkAvailable()) return; if (e.InitParams.Any()) { if (e.InitParams["firstControl"] != null) LoadControl( (Control) Activator.CreateInstance( sender.GetType().Assembly.GetType(e.InitParams["firstControl"]))); } else { LoadControl( (Control) Activator.CreateInstance( sender.GetType().Assembly.GetType("EMASolutions.CMS.Plugins.Silverlight.FolderBrowser"))); } RootVisual = Container; }
Notice, if the type was not specified, we can load a default control. Again, this is a simple example and the default control could be a persisted value also.
In this example, I am making use of a variable called Container, defined like so.
public static readonly Master Container = new Master();
Master has the following xaml and the default code behind.
<UserControl x:Class="EMASolutions.CMS.Plugins.Silverlight.Master" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <Grid x:Name="LayoutRoot"> <Grid.RowDefinitions> <RowDefinition Height="30" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Grid Name="TopBar" Grid.Column="0" Grid.Row="0"></Grid> <Grid Name="Main" Grid.Column="0" Grid.Row="1"></Grid> </Grid> </UserControl>
All that master does, is give us place holders to load our control into, one called Main and one called TopBar. In the Application_Startup method you will also notice the use of a method called LoadControl. This is what loads controls into our container. It is defined like so.
public static void LoadControl(Control control) { if (Container.Main.Children.Any()) LastControl = (Control)Container.Main.Children.First(); Container.Main.Children.Clear(); Container.TopBar.Children.Add(new TopBar()); Container.Main.Children.Add(control); }
We set a LastControl value if there was one, so that we can navigate backwards and then we clear the current controls and add our new control and a TopBar control.
We can also make use of the LoadControl method in other controls. For example, if we have an Authenticate control that logs in a user, we may wish to load another control if authentication failed. We could do this like so.
if (OnFailedAuthentication != null) { OnFailedAuthentication(sender,e); App.LoadControl(new Unauthorised()); }
Creating a reusable Silverlight login window – part 2
This is part 2 on how to create a reusable login window for Silverlight, part 1 is here.
The Authenticate.xaml child window created in the last post has evolved a little, instead of using Actions it now uses regular old events.
public partial class Authenticate : ChildWindow { #region "Properties" private readonly AuthenticationContext _authContext = new AuthenticationContext(); public static String Email { get; set; } public static event EventHandler OnBeforeAuthentication; public static event EventHandler OnAuthenticated; public static event EventHandler OnAfterAuthentication; public static event EventHandler OnFailedAuthentication; public static Boolean IsAuthenticated { get; set; } #endregion public Authenticate() { InitializeComponent(); if (IsAuthenticated) if (OnAuthenticated != null) OnAuthenticated(this, null); } private void OKButton_Click(object sender, RoutedEventArgs e) { DialogResult = true; if (OnBeforeAuthentication != null) OnBeforeAuthentication(sender,e); _authContext.Authenticate( Username.Text, Password.Password, delegate(InvokeOperation<Boolean> inv) { IsAuthenticated = inv.Value; if (inv.Value) { Email = Username.Text; IsAuthenticated = true; if (OnAuthenticated != null) OnAuthenticated(sender, e); } else { IsAuthenticated = false; if (OnFailedAuthentication != null) { OnFailedAuthentication(sender,e); } } }, null); if (OnAfterAuthentication != null) OnAfterAuthentication(sender,e); } private void CancelButton_Click(object sender, RoutedEventArgs e) { if (OnFailedAuthentication != null) { OnFailedAuthentication(sender,e); App.LoadControl(new Unauthorised()); } DialogResult = false; } }
I also made the EventHandlers static so that multiple controls can wire up delegates.
I added a new UserControl (AuthenticateControl.xaml) in order to house the Authenticate child window. The xaml for this control only contains the following.
<UserControl x:Class="EMASolutions.CMS.Plugins.Silverlight.Controls.AuthenticateControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > </UserControl>
The code behind contains the following.
public partial class AuthenticateControl : UserControl { public Boolean RequiresAuthentication { get; set; } public Authenticate LoginControl { get; set; } public AuthenticateControl() { InitializeComponent(); LoginControl = new Authenticate(); Loaded += Control_Loaded; } void Control_Loaded(object sender, RoutedEventArgs e) { if (!RequiresAuthentication) return; LoginControl = new Authenticate { Title = "Authenticate" }; if (!Authenticate.IsAuthenticated) LoginControl.Show(); Authenticate.OnFailedAuthentication += delegate { LoginControl.Show(); }; } }
This control is going to become a base control for our others to inherit from. In our other controls we can then set the RequiresAuthentication property to true and if the user has not yet authenticated they will be prompted to do so.
Here is an example of how we can use it in a control.
public partial class FolderBrowser : AuthenticateControl { public FolderBrowser() { _folderContext = new FolderContext(); _documentContext = new DocumentContext(); InitializeComponent(); Loaded += MainPage_Loaded; } void MainPage_Loaded(object sender, RoutedEventArgs e) { RequiresAuthentication = true; Authenticate.OnBeforeAuthentication += delegate { Dispatcher.BeginInvoke( () => { IsBusy = true; }); }; Authenticate.OnAuthenticated += delegate { _folderContext.Load( _folderContext.GetFoldersQuery(), LoadBehavior.RefreshCurrent, delegate { Dispatcher.BeginInvoke ( () => { folders.ItemsSource = _folderContext.Folders.Where(f => f.ParentId == 0); IsBusy = false; } ); }, null); }; } }
Notice this control now inherits from AuthenticateControl, the xaml must also be changed to include the AuthenticateControl as its root tag in place of UserControl.
In other controls, that do not require any sort of authentication we dont have to inherit from AuthenticateControl, we can just inherit from UserControl.
We can still make use of the static event handlers in the Authenticate child window, consider the following as an example.
public partial class TopBar : UserControl { public TopBar() { InitializeComponent(); Authenticate.OnAuthenticated += delegate { Email.Text = Authenticate.Email; }; } }
This simply appends an additional action to the OnAuthenticated event handler, so if a user has Authenticated using a control that required it we can tap in an use the email address they authenticated with to display it on screen.
Using this method we can be flexible in displaying authentication prompts and we can also allow dynamic loading of any control as the RootVisual in our Silverlight application.
This means we can pass a parameter from the server when the Silverlight application launches and define which control we want as our root visual based on something a user did. We dont have to direct them to a login area by default. We just allow our control to handle that.
I hope this makes sense, it seems like a nice way of doing things to me but I’m not sure I’ve explained it well. I’m still learning about the best way of doing things with Silverlight, so take everything with a ‘large’ pinch of salt.
Creating a reusable Silverlight login window – part 1
This post is an example showing how to create a reusable child window to allow a user to login to a silverlight application.
The first thing to do is add a new child window to your existing Silverlight project and name it Authenticate.xaml

Once we have added this item we can modify the xaml to meet our needs. I added a small message, a text box and a passsword box. I made use of the 2 buttons created in a child window by default. This is the xaml I ended up with.
<controls:ChildWindow xmlns:expressionDark="clr-namespace:System.Windows.Controls.Theming;assembly=System.Windows.Controls.Theming.ExpressionDark" x:Class="EMASolutions.CMS.Plugins.Silverlight.FolderBrowser.Authenticate" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls" xmlns:themeing="clr-namespace:System.Windows.Controls.Theming;assembly=System.Windows.Controls.Theming.Toolkit" Width="400" Height="300" Title="Authenticate"> <Grid x:Name="LayoutRoot" Margin="2"> <expressionDark:ExpressionDarkTheme> <StackPanel> <StackPanel Orientation="Vertical"> <Border Margin="2,2,2,2" Padding="2,2,2,2" Background="#333333" BorderThickness="1" BorderBrush="#000000" CornerRadius="2,2,2,2" > <TextBlock Height="130" TextWrapping="Wrap" Foreground="#FFFFFF" Text="Please login"> </TextBlock> </Border> <TextBox Margin="2,2,2,2" themeing:ImplicitStyleManager.ApplyMode="Auto" Name="Username" Text="Enter username" /> <PasswordBox Margin="2,2,2,2" themeing:ImplicitStyleManager.ApplyMode="Auto" Name="Password" PasswordChar="*" /> <StackPanel Orientation="Horizontal" HorizontalAlignment="Right"> <Button x:Name="CancelButton" HorizontalAlignment="Right" themeing:ImplicitStyleManager.ApplyMode="Auto" Content="Cancel" Click="CancelButton_Click" Width="75" Height="23" Margin="2,2,2,2" /> <Button x:Name="OKButton" HorizontalAlignment="Right" themeing:ImplicitStyleManager.ApplyMode="Auto" Content="Login" Click="OKButton_Click" Width="75" Height="23" Margin="2,2,2,2" /> </StackPanel> </StackPanel> </StackPanel> </expressionDark:ExpressionDarkTheme> </Grid> </controls:ChildWindow>
This gives us a child window that looks like the image below.
Next we need to open the code behind for this file. In this file we have added some actions to execute in various scenarios. The code looks like so.
public partial class Authenticate : ChildWindow { #region "Properties" private readonly AuthenticationContext _authContext = new AuthenticationContext(); public Action BeforeAuthentication { get; set; } public Action OnAuthenticated { get; set; } public Action AfterAuthentication { get; set; } public Action OnFailedAuthentication { get; set; } public bool IsAuthenticated { get { return (bool)GetValue(IsAuthenticatedProperty); } set { SetValue(IsAuthenticatedProperty, value); } } public static readonly DependencyProperty IsAuthenticatedProperty = DependencyProperty.Register("IsAuthenticated", typeof(bool), typeof(Authenticate), new PropertyMetadata(false)); #endregion public Authenticate() { InitializeComponent(); } private void OKButton_Click(object sender, RoutedEventArgs e) { DialogResult = true; if (BeforeAuthentication != null) BeforeAuthentication(); _authContext.Authenticate( Username.Text, Password.Password, delegate(InvokeOperation<Boolean> inv) { IsAuthenticated = inv.Value; if (inv.Value) { IsAuthenticated = true; if (OnAuthenticated != null) OnAuthenticated(); } else { if (OnFailedAuthentication != null) OnFailedAuthentication(); } }, null); if (AfterAuthentication != null) AfterAuthentication(); } private void CancelButton_Click(object sender, RoutedEventArgs e) { DialogResult = false; } }
In this example I call out to a RIA service to validate the username and password supplied by the user. Obviously this can be replaced to use other methods.
You can then make use of this child window in your xaml user control with code similar to the following.
void MainPage_Loaded(object sender, RoutedEventArgs e) { var login = new Authenticate {Title = "Authenticate"}; if (!login.IsAuthenticated) login.Show(); login.BeforeAuthentication = () => { Dispatcher.BeginInvoke( () => { IsBusy = true; }); }; login.OnAuthenticated = ()=> { _folderContext.Load( _folderContext.GetFoldersQuery(), LoadBehavior.RefreshCurrent, delegate { Dispatcher.BeginInvoke ( () => { folders.ItemsSource = _folderContext.Folders.Where(f => f.ParentId == 0); IsBusy = false; } ); }, null); }; login.OnFailedAuthentication = () => { login.Show(); }; }
In this example, we set a busy indicator using the BeforeAuthentication action, then using the OnAuthentication action we load some data and finally we wire up the OnFailedAuthentication to show the login window again.
This example is by no means perfect, but its a start, it only really works well in the context of simple Silverlight projects consisting of 1 user control. In a future post I’m going to expand on this and show it working in a more complex situation.
