您的位置:首页 > 其它

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

2013-08-23 16:22 429 查看

前言

通过前面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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐