Adding settings to your custom LightSwitch shell extension.

A couple of weeks ago, when LightSwitch was still in beta 2, I spent some time creating a custom LightSwitch shell for demo purposes.

Custom shell - storeworld style

Custom shell - storeworld style

When I tried to reuse the shell in a different project, it quickly came to my attention that there is something fundamentally wrong with it: I have no way to replace the company logo (bottom right corner).  When installing my shell extension, all LightSwitch is giving me is a combobox to enable it, but no way to add custom settings to my shell.

Selecting the custom shell

Selecting the custom shell

Now, I’ve got myself a serious problem.  With the speed of development that LightSwitch gives me, I might be finishing products for multiple customers on a daily bases now, but I have no way to “pimp” those projects to a personal level.

In comes the VsExportProviderService to the rescue.  From what I understand, it’s LightSwitch’s wrapper around a MEF catalog.  This means that I can use it not only to get an instance of that IServiceProxy that’s so important (because it has properties to all the components I need to build my standard shell), but also to shoot all kinds of exports all over my LightSwitch applications.

Let’s rework the example  from the previous post, (posted by the amazing LightSwitch team in their walktrough),  to show you what I mean.

First, find the “Current User: ” TextBlock in the ShellSample.xaml file, and replace it with the following:

 <StackPanel Orientation="Horizontal" >
   <TextBlock Name="CompanyNameTextBlock" Grid.Column="0" Style="{StaticResource TextBlockFontsStyle}" Foreground="{StaticResource NormalFontBrush}"/>
   <TextBlock Text=" - Who's logged in: " Grid.Column="0" Style="{StaticResource TextBlockFontsStyle}" Foreground="{StaticResource NormalFontBrush}"/>
 </StackPanel>

Note to self: write the blog post, get some sleep, enable code colouring on the blog in the morning and find out why my code isn’t being cropped, sorry about that (you can still copy & paste though)!

Next up, in the constructor of our ShellSample class, lets assign a value to the freshly created CompanyNameTextBlock’s Text property:

 public ShellSample()
 {
   this.InitializeComponent();
   //Add the lines below
   string CompanyName;
   if (!VsExportProviderService.TryGetExportedValue<string>("ShellSettings.CompanyName", out CompanyName))
   {
     CompanyName = "Default Company Name";
   }
   CompanyNameTextBlock.Text = CompanyName;
   //... rest below ...

What the code does is trying to find any string that was exported under the contractname of “ShellSettings.CompanyName”.  Because it will not find one, it will initialize my string to “Default Company Name”.  Running the application, it should come to no surprise that this is the result:

Shell without an export

Shell without an export

Now, lets export a string under the “ShellSettings.CompanyName” contract and see how the application changes.

Add a class to the Presentation.Shells folder of your ShellExtension.Client project, I named mine “ShellSettings”, containing the code below:

using System.ComponentModel.Composition;

namespace ShellExtension.Presentation.Shells
{
    public class ShellSettings
    {
        public ShellSettings() {
            this.CompanyName = "Contoso";
        }

        [Export("ShellSettings.CompanyName")]
        public string CompanyName { get; private set; }
    }
}

Run the project again and witness the magic happening:

Shell with an export

Shell with an export

Shell with an export - closeup

Shell with an export - closeup

Nice!  The shell extension found our company name, simply by having it anywhere in the project, and adding an Export attribute with the correct contractname.

We’re just one step away from succeeding in our goal: and that is to delete the ShellSettings class in our extension’s Client project, and add it to the LightSwitch project (mine is called ShellExtension.TestArea).  To do this, select your LightSwitch project and switch to File View from the Solution Explorer toolbar.  (The button is indicated by the red arrow in the screenshot below).  You can now see the Client, Common and Server projects inside your LightSwitch project.  RightClick on any of them (although the Client project makes most sence), and add the ShellSettings class like you normally would. Hit F5 to start your LightSwitch application:

Shell with values exported in our lightswitch application

Shell with values exported in our lightswitch application

Mission accomplished.  Altough the idea is quite simple, it is really powerful: my shell extension is having it’s properties set by simple Exports in my LightSwitch application.

I’d like to close my second blog post with a question…  To keep this example simple, I exported only one setting, using a string (“ShellSettings.CompanyName”), which really isn’t a good practise.  Ofcourse, for my real applications I export under a contract in a shared library that I will use / support in every custom shell I’ll make:

    [InheritedExport(typeof(IShellSettings))]
    public interface IShellSettings {
        string CompanyName { get; }
        Uri BackgroundImage { get; }
        Uri CompanyLogoSmall { get; }
        Uri CompanyLogoLarge { get; }
        // ...

If this idea of exporting shell settings catches on, and unless someone has a better idea (anyone knows how to add a custom tab to the LightSwitch application properties?), perhaps we can agree on a common IShellSettings interface and put it up on CodePlex?

Advertisements

6 thoughts on “Adding settings to your custom LightSwitch shell extension.

  1. Great article! Just finished building a larger SilverLight LOB in PRISM used a ton of MEF within MVVM and absolutely love the whole MEF approach.
    I can see through the various under-pinnings that LightSwitch is built around MEF and the Aggregate Catalog approach which is pretty cool.
    I just started to play with LightSwitch yesterday and I love it albeit there needs to be more documentation.
    Here is a link to my struggles creating my own custom shell for LightSwitch. Although not feature rich and I did struggle connecting the dots, I think I am going to really enjoy this ride!

    Keep up the great articles!

    http://social.msdn.microsoft.com/Forums/en-US/lsextensibility/thread/2250a644-5be1-47b1-8689-fad68474df46

    • Hey John!
      Thanks for your kind words! My team also spent the last 3 years working on a large LOB application (using MEF, Caliburn, WPF and a service oriented architecture (WCF)). It’s amazing to see how much features of our homebrew framework are implemented in a fairly similar way in LightSwitch… (But ofcourse, LightSwitch has much more to offer then our framework, lol!)
      Your custom shell looks amazing! Really good job there! Can’t wait till you finish it! 🙂

      Kind regards

      Jan

  2. Thanks Jan there is still lots to do.

    The one thing that I wish I could source is better documentation on advanced LightSwitch development, which is why I was drawn to your Blog posts.

    Do you happen to have any links that you could share with us LightSwitch wananbies and newbies?

    One other thing that concerns me a little with LightSwitch, is that I got very use to building Modules within PRISM so that I could offer and segment Business functionality in Modules, that were discovered at runtime. This allows me to position Module development to separate teams to work in isolation and then inject these Modules into the UI and application at runtime. To me at least, it becomes a much easy thing to manage especially when creating a large set of LOB functionality.

    Perhaps its that lack of documentation I seek that gives me this sense of uneasiness that LightSwitch doesn’t have a good Enterprise development approach or perhaps its because I am still new to it all. I’d be interested to learn what others think about that and some of the techniques that we can employee to organize LightSwitch projects to be more manageable in that sense.

    I believe that had Microsoft leveraged the MEF Catalog and PRISM Module type approach, where you could create separate loosely coupled Modules through Interface definition, that this would provide a much better development approach.
    Like I said, it’s just a concern, likely one that is less warranted than its worth discussing.

    Regardless, I love LightSwitch and I see this saving our organization hundreds of thousands of dollars over the next few years, if not millions. I know to some of you out there, this may seem like a ridiculous statement, but if you have ever been responsible for 100K business users running your applications, strewn across the globe, who have and want flexible LOB applications with as little a cost as possible, I can assure you, LightSwitch has what it takes to provide that level of LOB and user base support. I know that the technology does work because we have built a ton of SilverLight/WCF RIA service solutions and they simply are far easier to build, deploy and maintain. LightSwitch is a quantum leap forward in the LOB space. It’s definitely got the legs and I can’t wait to dig in deeper!

    Thanks again for providing this Blog site, I really have enjoyed all that you have written on this subject. Please keep up the great work!

    • Hey John!
      Wow what a comment!
      First off all, thank you for your kind words towards my blog. Having positive reactions like this one is extremely motivating!
      I do not know all good links by heart, but I’m working on a “recommended reading” section, hopefully have a thourough list by this weekend…
      Lastly, the multi module approach you mention is something that has been one my mind since day one aswell, so much even, that I’ll blog on it later tonight…

      Kind regards

      Jan

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s