在之前的一篇文章中,讨论了MEF(Managed Extensibility Framework)的基础知识,并通过一个简单的控制台应用程序进行了演示。希望那篇文章对理解MEF的基本概念有所帮助,比如导入(Importing)、导出(Exporting)、目录(Catalog)、容器(Container)等。本文将指导创建一个使用MEF的简单Silverlight应用程序。如果是MEF的新手,强烈建议阅读前一篇文章以获取MEF的基础知识。阅读完本文后,如果有任何疑问,请随时告诉,会尽快回答。非常重视宝贵反馈。
要开始使用Silverlight和MEF应用程序,需要设置开发环境。在开发计算机上,需要预先安装以下工具:
一旦环境准备好了上述工具,就可以开始下一步了。
首先,需要创建一个Silverlight应用程序项目,然后添加一些程序集引用以便使用MEF。按照以下步骤设置项目:
完成上述所有步骤后,项目就准备好进行MEF开发了。
首先,来决定示例要做什么。将创建一个Silverlight应用程序,其中包含一些作为小部件的UserControl。这是出于学习目的,因此不要关注UI。在示例应用程序中,将创建一个UserControl并将其标记为可导出的。然后将在应用程序中导入UserControl以将其添加到UI中。接下来,将创建另一个UserControl并将其标记为可导出的,以便在不更改代码的情况下将其添加到主UI中。这只是一个示例,用于展示Silverlight应用程序中的MEF功能。
让进入代码。首先,将创建一个名为IWidget的接口,并使用此接口构建UserControl。将继承此接口到UserControl,而在导出或导入时,将使用相同的接口类型。这样做的原因是确保只有指定类型的控件将被标记为MEF。如果为两种不同类型的控件使用两种不同的类型,那么在主屏幕中管理起来将更容易。因此,只需创建一个名为IWidget的空白接口,如下所示:
public interface IWidget
{
// 定义接口内容
}
现在,在MainPage.xaml中,添加一个ItemsControl并将其命名为“widgets”。用一个StackPanel包裹ItemsControl以容纳项目。XAML文件将如下所示:
<StackPanel>
<ItemsControl Name="widgets">
</ItemsControl>
</StackPanel>
现在是时候创建一个UserControl了。右键单击Silverlight项目并添加一个UserControl,将其命名为“EmployeeWidget”。不会在其中设计更多内容,因为这不是必须的,以理解MEF。为了使其更易于查看,只需添加一个带有一些字符串的TextBlock。在示例中,将“Employee Widget”设置为TextBlock的文本字符串,并为Grid背景设置颜色“Red”。将UserControl调整为150 x 150,以便它在屏幕上正确设置。让看看下面的代码以获取详细的布局:
<UserControl x:Class="MEFWithSilverlightDemo.EmployeeWidget"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="150" Height="150"
Background="Red">
<TextBlock Text="Employee Widget" Foreground="White"/>
</UserControl>
如上所述,将控件调整为150 x 150,然后更改背景颜色为Red。添加了一个TextBlock,其值为“Employee Widget”,设置TextBlock的TextProperty为“Employee Widget”,前景颜色为White,以便在Red颜色上方可见。不需要对此进行更多描述。只需查看上面的XAML,就会了解其背后的想法。
按下EmployeeWidget.xaml页面上的F7键以打开背后的代码文件。从IWidget继承EmployeeWidget类。完成后,向类添加类型为IWidget的“Export”属性。这将确保该类将导出以满足MEF。请查看以下代码:
[Export(typeof(IWidget))]
public partial class EmployeeWidget : UserControl, IWidget
{
// 类的实现
}
由于UserControl已导出以满足MEF,现在是时候在MainPage中导入它了。为此,请打开MainPage.xaml.cs,并创建一个IWidget类型的属性“Widgets”。使用数组类型以确保可以在那里导入许多小部件。因此,用类型为IWidget的“ImportMany”属性标记该属性。完成后,代码已准备好导入导出的类。现在在MainPage构造函数中,遍历数组并将所有小部件作为项目添加到在XAML中已经添加的“widgets”项目控件中。现在如果运行应用程序,会注意到Widgets数组是null。为什么?好好想想。哦,是的!忘记了满足MEF Initializer以满足属性。该怎么做呢?为了满足导入,需要在遍历数组列表之前调用“CompositionInitializer.SatisfyImports(this);”。请查看以下代码:
public partial class MainPage : UserControl
{
[ImportMany(typeof(IWidget))]
public IEnumerable<IWidget> Widgets { get; set; }
public MainPage()
{
InitializeComponent();
CompositionInitializer.SatisfyImports(this);
foreach (var widget in Widgets)
{
widgets.Items.Add(widget);
}
}
}
现在,再次运行应用程序,这次将看到EmployeeWidget添加到了UI屏幕中,文本为“Employee Widget”,背景为Red。这里是相同的截图:
哇哦!没有创建UserControl的对象并将其添加到ItemsControl中。MEF框架为完成了。一旦满足,它就创建了对象并将其导入到MainPage中。
就是这样。现在将再做一件事。将创建另一个名为“CustomerWidget”的UserControl,并按照上述步骤导出控件。这次,将将文本设置为“Customer Widget”,并将背景颜色设置为Green。这将使能够轻松区分项目。这里是CustomerWidget用户控件的XAML代码:
<UserControl x:Class="MEFWithSilverlightDemo.CustomerWidget"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="150" Height="150"
Background="Green">
<TextBlock Text="Customer Widget" Foreground="White"/>
</UserControl>
现在通过在XAML页面上按F7键打开CustomerWidget的代码背后的文件,并按照为EmployeeWidget所做的步骤进行操作,即实现名为IWidget的接口的CustomerWidget,并设置类为可导出的,通过设置IWidget的Export属性。这是参考的代码:
[Export(typeof(IWidget))]
public partial class CustomerWidget : UserControl, IWidget
{
// 类的实现
}