Click here to Skip to main content
16,016,882 members
Articles / Desktop Programming / WPF
Tip/Trick

Integrate Popular WPF Modern UI with OSGi.NET

Rate me:
Please Sign up or sign in to vote.
4.80/5 (6 votes)
10 Jul 2013GPL35 min read 37.5K   1.2K   12   14
This tip describes how to integrate Modern UI with OSGi.NET.

Introduction

Several months ago, I wrote an article about the usage of a modularization framework called OSGi.NET. Today, let's have a took at how to integrate a very popular UI framework called "Modern UI For WPF" with OSGi.NET and make this UI modularized.

What's Modularized for?

In general WPF application, we combine all pages (UI) and code-behind (business logic) together in one executable file, that means if we modify any UI or logic later we need to rebuild the whole solution, even the unchanged part. How can we avoid this? One option is modularization, divide a whole into several small parts by its UI or logic, then we put them together as complete one when running. The benefit is that you just need focus on the part that will be changed and bring the minimum risk or bugs into all.

What's OSGi.NET For?

We all know it's easy to modularize the logic as we could build different logic into different assemblies, but how about UI? Can we have an easy way to do the same modularization with UI and put different small UIs together as one later too? And how about put UI and its logic together in one assembly? More, can we stop/start/install/uninstall any individual part without application restarting? Even more, can we add/remove any individual part without rebuilding? Yes, that's what OSGi.NET can probably do!

OK, let's see this Modern UI with OSGi.NET for real.

Image 1

Link demo1 and demo2 are from DemoPlugin, demo3 is from DemoPlugin2, PLUGIN MANAGEMENT is from UIShell.WpfAppCenterPlugin.

Image 2

How did this happen?

  1. First, we need a Shell to be the Host application (all small individuals as Plugin that will be installed into Host later). Host defines the basic UI and Extension Point for the Plugins.

    Extension Point (as EP below) is the "Entry Point" for Plugin to inject information to Host or we can simply say through EP, Host will include Plugin into itself. That's a common way we combine individual into one in OSGi.NET. BTW, EP is a kind of Communication Contract, it has a unique name, so we can add more than one EP at the same time. For more information about EP, please reference "OSGi.NET - An OSGi-based modularization framework for .NET".

    Here we pre-define one EP, named "UIShell.WpfShellPlugin.LinkGroups", which is used to add the Links of Plugins in the red box of the below image.

    Image 3

  2. Next, we're going to get Plugin ready and tell the Host we need to put ourselves into it and display. Again, we need EP, every Plugin has to follow the same EP name, as above, "UIShell.WpfShellPlugin.LinkGroups". BTW, to Plugin, this definition we call it "Extension", that means Extension Point and Extension always appear in pairs.

    When application is launching, OSGi.NET will search, analyse and collect every Extension definition from all Plugins before Host is displayed. Then Host will use them to decide how to show the Link on Host UI and what action will trigger if the Link is clicked. In this Modern UI, click a Link text Main Window will redirect to page binded with.

Background

Modern UI for WPF, a set of controls and styles converting your WPF application into a great looking Modern UI app. This open source project is a spin-off of XAML Spy, the visual runtime inspector for Silverlight, Windows Phone, Windows Store and WPF. Read the announcement at xamlspy.com.

OSGi.NET, a dynamic modularization framework, which is a .NET implementation tightly based on OSGi specifications from OSGi Alliance, is designed and developed by Xi’an UI Information Technology, Inc., in China, from 2008.

Using the Code

Let's see how to add a fresh new demo page into the current solution.

  1. Right click on "AppPlugins" and add a new project "MyDemoPlugin", please note the Location is under "bin\plugins", that's where OSGi.NET search and load.

    Also we always change the Output path for both Debug and Release to "bin\" as default.

    Image 4

  2. Add the missing references, below it's how it looks when done:

    Image 5

  3. Next add WPF UserControl file named "UserControl1.xaml" at root of MyDemoPlugin.
    XML
     <UserControl x:Class="MyDemoPlugin.UserControl1"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 xmlns:mui="http://firstfloorsoftware.com/ModernUI"
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300">
        <Grid Style="{StaticResource ContentRoot}">
            <ScrollViewer>
                <StackPanel >
                    <TextBlock Text="MyDemo" Style="{StaticResource Heading1}" Margin="0,0,0,8"/>
                    <TextBlock />
                    <mui:BBCodeBlock BBCode="This is my demo." Margin="0,0,0,32" />
                </StackPanel>
            </ScrollViewer>
        </Grid>
    </UserControl> 

    Then, we add an XML file at the root of MyDemoPlugin named "Manifest.xml".

    XML
    <?xml version="1.0" encoding="utf-8"?>
    <Bundle xmlns="urn:uiosp-bundle-manifest-2.0" 
    Name="My Demo Plugin" SymbolicName="MyDemoPlugin" 
    Version="1.0.0.0" InitializedState="Active">
      <Runtime>
        <Assembly Path="bin\MyDemoPlugin.dll" Share="false" />
        <Dependency BundleSymbolicName="UIShell.WpfShellPlugin" 
        Resolution="Mandatory" />
      </Runtime>
      <Extension Point="UIShell.WpfShellPlugin.LinkGroups">
        <LinkGroup DisplayName="MyDemo" 
        DefaultContentSource="MyDemoPlugin.UserControl1">
          <Link DisplayName="MyDemoMenu1" 
          Source="MyDemoPlugin.UserControl1" />
        </LinkGroup>
      </Extension>
    </Bundle>  

    Here let's explain the "Extention", the Point indicates that this Plugin will match pre-defined EP above, or this Plugin will display in Host. Inner XML indicates the Display Name, the Default Content Source after click the Link or Menu.

    Note: We don't show the code of how Host handles the Extension XML, please reference \UIShell.iOpenWorks.WPF\bin\Plugins\UIShell.WpfShellPlugin\ExtensionModel\ShellExtensionPointHandler.cs and learn how to transfer this into an object we want.

  4. All right, seems everything is ready, let's just RUN it to press F5, here we go! Quite simple!

    Image 6

Points of Interest

In this solution, we provide some Plugins as default.

With Plugin Management, you can stop/start/uninstall any plugin with Running.

Image 7

With Plugin Center, you can easily install more plugins from a remote repository.

Image 8

I will leave you readers something interesting to test by yourself.

Launch the application and try to Stop "MyDemoPlugin" in Plugin Management, then back to Main Page.
  • Then try to start it and back again.
  • Close the application and try to backup and delete "MyDemoPlugin" folder in "bin\plugins" and Launch it.
  • Close the application and copy the backup "MyDemoPlugin" to "bin\plugins" and launch it.

History

  • 9 Jul 2013 - Created the article
  • 10 Jul 2013 - Added more explanation
  • 11 Jul 2013 - Re-uploaded the missing files and images

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)


Written By
Program Manager Xi’an UI Information Technology, Inc.
China China
8+ yr. work experience, 7+ yr. with ASP.NET, 2+ yr. Build & Install with WiX.
Interest on OSGi, OpenStack and WiX

Comments and Discussions

 
QuestionNice framework but need help on demo project Pin
Mike Prager25-Jun-16 22:40
Mike Prager25-Jun-16 22:40 
QuestionIts not working Pin
Member 1219496928-Dec-15 21:55
Member 1219496928-Dec-15 21:55 
QuestionVB.NET Pin
User 967321312-Nov-13 8:36
User 967321312-Nov-13 8:36 
AnswerRe: VB.NET Pin
Sam Ma, Xi'an2-Dec-13 19:25
Sam Ma, Xi'an2-Dec-13 19:25 
GeneralMy vote of 5 Pin
Prasad Khandekar13-Oct-13 23:59
professionalPrasad Khandekar13-Oct-13 23:59 
QuestionSample Application is not working Pin
Member 6861816-Jul-13 7:10
Member 6861816-Jul-13 7:10 
Any idea how to solve this issue:
exception about start:

var pageFlowService = bundleRuntime.GetFirstOrDefaultService<IPageFlowService>();
if (pageFlowService == null)
{
throw new Exception("The page flow service is not installed."); app crash here
}

Thank you in advance.
AnswerRe: Sample Application is not working Pin
Sam Ma, Xi'an22-Jul-13 4:29
Sam Ma, Xi'an22-Jul-13 4:29 
GeneralMy vote of 5 Pin
JoeyZhao10-Jul-13 22:48
JoeyZhao10-Jul-13 22:48 
QuestionNot Work Pin
Patrick Blackman10-Jul-13 19:23
professionalPatrick Blackman10-Jul-13 19:23 
AnswerRe: Not Work Pin
Sam Ma, Xi'an10-Jul-13 20:55
Sam Ma, Xi'an10-Jul-13 20:55 
GeneralMy vote of 1 Pin
Eric Lapouge10-Jul-13 2:41
Eric Lapouge10-Jul-13 2:41 
GeneralRe: My vote of 1 Pin
Sam Ma, Xi'an10-Jul-13 7:57
Sam Ma, Xi'an10-Jul-13 7:57 
GeneralRe: My vote of 1 Pin
Eric Lapouge10-Jul-13 17:05
Eric Lapouge10-Jul-13 17:05 
GeneralRe: My vote of 1 Pin
Sam Ma, Xi'an10-Jul-13 17:53
Sam Ma, Xi'an10-Jul-13 17:53 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.