MEF学习系列(6): 在Silverlight中应用MEF

前言

通过前面MEF的基础知识的学习,我们已经知道MEF可以在控制台程序中寄宿。MEF还可以在Winform,Silverlight,WPF等应用程序中使用。在接下里的几篇文章中我们就重点介绍MEF是如何在这些应用程序中使用的。本文通过一个例子介绍MEF在Silverlight中的简单应用。

正文

第一步:打开VS新建一个Silverlight应用程序,命名为MEFDemo_SL。一路默认。

完整的Solution结构如下:

在MainPage的设计器中添加一个容器控件,我们这里添加一个TabControl(Name设置为“tcContainer”)。

<UserControl x:Class="MEFDemo_SL.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"
             xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <sdk:Label Grid.Row="0" Margin="10" FontSize="24" HorizontalAlignment="Left"
                   Name="label1" VerticalAlignment="Top" Content="在Silverlight中使用MEF示例"/>
        <sdk:TabControl Grid.Row="1" HorizontalAlignment="Left" Name="tcContainer" VerticalAlignment="Top"
                        Width="500" Height="300">
            <sdk:TabItem Header="MyTab1" Name="tiTabItem1"></sdk:TabItem>
            <sdk:TabItem Header="MyTab2" Name="tiTabItem2">
                <Button HorizontalAlignment="Center" VerticalAlignment="Center"
                        Height="27" Width="100" Content="转到MyTab1"></Button>
            </sdk:TabItem>
        </sdk:TabControl>
    </Grid>
</UserControl>


 

第二步:添加一个Silverlight类库,命名为“MEFDemo_SL.Contract”。删除默认的class1,新建接口IMyPart。

namespace MEFDemo_SL.Contract
{
    public interface IMyPart
    {

    }
}


 

第三步:创建扩展控件。主要步骤为:

1. 添加一个Silverlight类库,命名为“MEFDemo_SL.Extensions”;

2. 删除默认类。添加“System.ComponentModel.Composition.dll”和项目MEFDemo_SL.Contract的引用,并在类上标记导出特性[Export(typeof(IMyPart))];

3. 新建用户控件命名为“MyExtension1”,使之实现接口IMyPart。并添加一个富文本控件“RichTextBox”命名为“rtbText”。

<UserControl x:Class="MEFDemo_SL.Extensions.MyExtension1"
    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"
    d:DesignHeight="600" d:DesignWidth="800">
    
    <Grid x:Name="LayoutRoot" Background="White">
        <RichTextBox HorizontalAlignment="Left" Margin="10" Name="rtbTest" VerticalAlignment="Top" Height="400" Width="600" BorderThickness="2" Background="Bisque" FontSize="20"/>
    </Grid>
</UserControl>


cs后台代码如下:

using System.Windows.Controls;
using System.ComponentModel.Composition;
using MEFDemo_SL.Contract;
using System.Windows;

namespace MEFDemo_SL.Extensions
{
    [Export(typeof(IMyPart))]
    public partial class MyExtension1 : UserControl,IMyPart
    {
        public MyExtension1()
        {
            InitializeComponent();
            
        }

        public void Test()
        {
            MessageBox.Show("I am Extension1 ");
        }
    }
}


第四步:操作MEFDemo_SL项目,实现在MainPage中加载扩展部件MyExtension1。

1. 在项目MEFDemo_SL中添加对MEFDemo_SL.Contract的项目引用。

2. 添加对程序集“System.ComponentModel.Composition.dll”和“System.ComponentMdel.Composition.Initialization.dll”的引用。

3. 定义ContractType为IMyPart的导入:

        //导入Import
        [ImportMany(typeof(IMyPart))]
        public IEnumerable<IMyPart> MyParts { set; get; }
        //也可以用Import来用,相应的需要在组合的时候就不需要使用foreah了
        //[Import(typeof(IMyPart))]
        //public IMyPart MyParts { set; get; }


 

4. 组合,为了使得扩展控件能够被加载我们添加对项目“MEFDemo_Extension1”的引用。下一篇我们会介绍如何动态加载XAP包。MainPage.cs代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using MEFDemo_SL.Contract;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;

namespace MEFDemo_SL
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();

            //第一种组合方式 也可以这么写
            //var catalog = new AggregateCatalog(new DeploymentCatalog());
            //var container = new CompositionContainer(catalog);
            //container.ComposeParts(this);

            //第二种组合方式
            CompositionInitializer.SatisfyImports(this);

            foreach (var part in MyParts)
            {
                tiTabItem1.Content = part;
                part.Test();
            }            
        }

        //导入Import
        [ImportMany(typeof(IMyPart))]
        public IEnumerable<IMyPart> MyParts { set; get; }
        //也可以用Import来用,相应的需要在组合的时候就不需要使用foreah了
        //[Import(typeof(IMyPart))]
        //public IMyPart MyParts { set; get; }
    }
}


运行结构如下:

先会弹出一个提示框,证明已经组合成功,并且调用了Extension1的Test方法。然后会打开如下界面

 

 

其实上面的功能如果不使用MEF的话,可以使用一下代码实现,由此可见MEF简化了引用类的引用及对象的常见工作:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using MEFDemo_SL.Contract;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using MEFDemo_SL.Extensions;

namespace MEFDemo_SL
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();

            //第一种组合方式 也可以这么写
            //var catalog = new AggregateCatalog(new DeploymentCatalog());
            //var container = new CompositionContainer(catalog);
            //container.ComposeParts(this);

            //第二种组合方式
            //CompositionInitializer.SatisfyImports(this);

            MyExtension1 ex1 = new MyExtension1();
            ex1.Test();

            tiTabItem1.Content = ex1;
            //foreach (var part in MyParts)
            //{
            //    tiTabItem1.Content = part;
            //    part.Test();
            //}            
        }

        //导入Import
        //[ImportMany(typeof(IMyPart))]
        //public IEnumerable<IMyPart> MyParts { set; get; }
        //也可以用Import来用,相应的需要在组合的时候就不需要使用foreah了
        //[Import(typeof(IMyPart))]
        //public IMyPart MyParts { set; get; }
    }
}


 源代码: http://download.csdn.net/detail/eric_k1m/6000079

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值