New Home..

December 19, 2009 Leave a comment

I’m migrating my blog over to here.

Head over there, there will be more code sample available there.

Categories: .NET Tags:

Getting started with Silverlight and MEF, Import and Export

December 18, 2009 Leave a comment

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.

kick it on DotNetKicks.com

RIA Services Examples – Using InvokeOperation

December 17, 2009 Leave a comment

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

December 12, 2009 Leave a comment

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

December 12, 2009 Leave a comment

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()); }

kick it on DotNetKicks.com

Follow

Get every new post delivered to your Inbox.