Coproject - a RIA Caliburn.Micro demo, part 3

In this third part, we will set up Caliburn.Micro to our client project and add some cool styles :-).

1. Project cleanup

Let’s create some structure in the project. Delete MainPage.xaml and create folders Assets, ViewModels, ViewModels/Interfaces, and Views. Your Solution Explorer should look like this:
image

Finally, to make the solution build, make function Application_Startup in App.xaml.cs empty (we have deleted MainPage).

2. Add Caliburn.Micro

Open Coproject client in Solution Explorer, and Add Reference to Caliburn.Micro.dll. You will probably have to browse for the file in /Bin/Release/ folder where you downloaded and built it in Step 0. Make sure that you reference the Silverlight version of C.M.

Add Bootstrapper

In root, create new class AppBootstrapper and make it inherit Caliburn.Micro.Bootstrapper. This works as C.M initialization and configuration. Now, since we want to use MEF as Dependency Injection container, we need to set the bootstrapper as follows:

public class AppBootstrapper : Bootstrapper
{
        private CompositionContainer _container;
 
        protected override void Configure()
        {
                InitializeContainer();
        }
 

        private void InitializeContainer()
        {
                AggregateCatalog catalog = new AggregateCatalog(
                                AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType<ComposablePartCatalog>());
 
                _container = CompositionHost.Initialize(catalog);
 
                var batch = new CompositionBatch();
 
                IEventAggregator eventAggregator = new EventAggregator();
                IWindowManager windowManager = new WindowManager();
                eventAggregator.Subscribe(windowManager);
 
                batch.AddExportedValue<IEventAggregator>(eventAggregator);
                batch.AddExportedValue<IWindowManager>(windowManager);
                batch.AddExportedValue(_container);
 
                _container.Compose(batch);
        }
 
        protected override object GetInstance(Type serviceType, string key)
        {
                string contract = string.IsNullOrEmpty(key) ? AttributedModelServices.GetContractName(serviceType) : key;
                var exports = _container.GetExportedValues<object>(contract);
 
                if (exports.Any())
                {
                        return exports.First();
                }
 
                throw new Exception(string.Format("Could not locate any instances of contract {0}.", contract));
        }
 
        protected override IEnumerable<object> GetAllInstances(Type serviceType)
        {
                return _container.GetExportedValues<object>(AttributedModelServices.GetContractName(serviceType));
        }
 
        protected override void BuildUp(object instance)
        {
                _container.SatisfyImportsOnce(instance);
        }
}

You’ll have to add references to:

System.ComponentModel.Composition
System.ComponentModel.Composition.Initialization

And add usings to (probably more usings will be needed, but these ones are not obvious):

using System.Linq;
using System.ComponentModel.Composition;

This will initialize MEF and let it auto discover exports throughout the whole assembly.

Note: Caliburn.Micro is not bound to any concrete implementation of DI, so you can set it to use Unity, Ninject, Castle Windsor container, or any other.

Add Shell

In ViewModels/Interfaces, create a new empty interface called IShell. We will use it to mark the main window (shell). Then, create Shell implementation:

[Export(typeof(IShell))]
public class ShellViewModel : Screen, IShell
{
}

Notice the Export attribute. It tells MEF to consider Shell an IShell implementation. So, if anyone ‘asks’ MEF for IShell implementation, MEF will provide a ShellViewModel instance.

Now, when we have simple shell viewmodel, we also need a view. Create a new Silverlight User Control in Views so that the project structure looks like:
image

Add a TextBlock with text Coproject to the view.

Link it all together

Now, when we have shell prepared, there are only two more things to do: notify C.M about our shell and bind the bootstrapper to application startup.

Setting up shell is easy – just change base class of AppBootstrapper from Bootstrapper to Bootstrapper<IShell>.

To make sure that our bootstrapper is run on application startup, we need to add it to application resources – it will then take care of everything else. To achieve this, update App.xaml as follows:

<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
                         xmlns:app="clr-namespace:Coproject"
                         x:Class="Coproject.App">
        <Application.Resources>
                <app:AppBootstrapper x:Key="AppBootstrapper" />
        </Application.Resources>
</Application>

We are done – make sure that Coproject.Web is your startup project and you can Run the application. You should see the text in ShellView.
image

Notice that we only told the application to use shell. There was no need to specify what view to show. This is caused by Caliburn.Micro and its ‘Convention over Configuration’ philosophy. It means that if you do the stuff right (this concerns mainly naming) , it will just work. We will see a lot more conventions of C.M later.

3. Add some style

Finally, let’s add some style sheets to make the application look better. In the Assets folder, create a new folder – Cosmopolitan and extract all seven files from the attached zip file to it.

Add references to these assemblies (make sure you choose the latest version if more than one is available):

System.Windows.Controls
System.Windows.Controls.Data
System.Windows.Controls.Data.Input
System.Windows.Controls.Data.DataForm.Toolkit
System.Windows.Controls.DataVisualization.Toolkit
System.Windows.Controls.Input
System.Windows.Controls.Input.Toolkit
System.Windows.Controls.Layout.Toolkit
System.Windows.Controls.Navigation
System.Windows.Controls.Toolkit

To register these resources in the application, edit App.xaml to look as follows (working with nested resource dictionaries might be tricky):

...
<Application.Resources>
        <ResourceDictionary>
                <ResourceDictionary.MergedDictionaries>
                        <ResourceDictionary Source="Assets/Cosmopolitan/Styles.xaml"/>
                        <ResourceDictionary Source="Assets/Cosmopolitan/CoreStyles.xaml"/>
                        <ResourceDictionary Source="Assets/Cosmopolitan/SDKStyles.xaml"/>
                        <ResourceDictionary Source="Assets/Cosmopolitan/ToolkitStyles.xaml"/>
                        <ResourceDictionary Source="Assets/Cosmopolitan/Custom.xaml"/>
                        <ResourceDictionary>
                                <app:AppBootstrapper x:Key="AppBootstrapper" />
                        </ResourceDictionary>
                </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
</Application.Resources>
...

Finally, update content of ShellView:

<Border x:Name="LayoutRoot" Style="{StaticResource ContentBorderStyle}">
        <Grid>
                <Border Style="{StaticResource LeftBorderStyle}"/>
                <ContentControl Style="{StaticResource LogoIcon}"/>
 
                <TextBlock Text="Coproject" Style="{StaticResource ApplicationTitleStyle}" />
        </Grid>
</Border>

And that is all for this part.
image

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值