代码改变世界

我学MEF系列(7):动态装配Silverlight组件

2011-12-29 13:12  ps_zw  阅读(1476)  评论(2编辑  收藏  举报

前言

上一篇文章具体介绍到了如何在Silverlight中使用MEF,为了使SL扩展控件能够组合成功,我们在MEFDemo_SL中添加了对项目MEFDemo_SL.Extensons的引用,并在MainPage中using了扩展控件的命名空间。这看似有点不合逻辑,的确,这么做怎么都觉得很怪异,组件应该能够被动态发现。本篇文章就介绍一下如何动态加载dll。

动态加载

动态发现并加载silverlight的dll,需要先使用webclient将dll下载到客户端,再使用MEF进行组合。我们对上一篇文章的例子进行简单的修改:

1.在MEFDemo_SL.Web中新建文件夹Parts,将MEFDemo_SL.Extensions.dll拷贝到该目录中;

image

2.在MainPage中加入一个Button用来触发动态加载,同时去除上篇我们添加的引用(对MEFDemo_SL.Estensions.dll的引用);

View Code
 1 <StackPanel Grid.Row="1">
2 <Button VerticalAlignment="Center" HorizontalAlignment="Left" Margin="20 50 20 10" Height="27" Width="100" Content="点击加载插件" Click="Button_Click" />
3 <sdk:TabControl HorizontalAlignment="Left" Name="tcContainer" VerticalAlignment="Top" Width="500" Height="300" Margin="12,10,0,0">
4 <sdk:TabItem Header="MyTab1" Name="tiTabItem1">
5 </sdk:TabItem>
6 <sdk:TabItem Header="MyTab2" Name="tiTabItem2">
7 <Button HorizontalAlignment="Center" Name="btnShowEditor" VerticalAlignment="Center" Height="27" Width="100" Content="转到MyTab1"></Button>
8 </sdk:TabItem>
9 </sdk:TabControl>
10 </StackPanel>

3.在Button的Click事件中使用WebClient异步下载MEFDemo_SL.Extensions.dll,在完成事件中完成部件的组合;

代码如下:经过上面几步骤的修改便可以使用MEF实现Silverlight组件的动态装配。

View Code
 1         /// <summary>
2 /// 按钮点击事件
3 /// </summary>
4 /// <param name="sender"></param>
5 /// <param name="e"></param>
6 private void Button_Click(object sender, RoutedEventArgs e)
7 {
8 LoadSLAssembly();
9 }
10
11 /// <summary>
12 /// 加载SL组件
13 /// </summary>
14 private void LoadSLAssembly()
15 {
16 if (Application.Current.Host.Source != null)
17 {
18 string uri = Application.Current.Host.Source.AbsoluteUri;
19 int index = uri.IndexOf("/ClientBin", StringComparison.Ordinal); //找出根URI
20 uri = uri.Substring(0, index) + "/Parts/MEFDemo_SL.Extensions.dll";
21
22 WebClient client = new WebClient();
23 client.OpenReadCompleted += ClientOpenReadCompleted;
24
25 //根据给定的URI,启动异步下载
26 client.OpenReadAsync(new Uri(uri));
27 }
28 }
29
30 /// <summary>
31 /// 下载完成时触发
32 /// </summary>
33 /// <param name="sender"></param>
34 /// <param name="e"></param>
35 void ClientOpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
36 {
37 //获取下载的SL程序集
38 AssemblyPart assemblyPart = new AssemblyPart();
39 Assembly assembly = assemblyPart.Load(e.Result);
40
41 //创建 AssemblyCatalog,并组合改目录
42 AssemblyCatalog catalog = new AssemblyCatalog(assembly);
43 CompositionContainer container = new CompositionContainer(catalog);
44
45 //组合(装配)当前对象
46 CompositionBatch bat = new CompositionBatch();
47 bat.AddPart(this);
48 container.Compose(bat);
49
50 //显示装配好的页面组件
51 foreach (var part in Parts)
52 {
53 tiTabItem1.Content = part;
54 }
55
56 this.btnLoading.Content = "加载成功!";
57 this.btnLoading.IsEnabled = false;
58 }


运行效果图:

image

到此已经我们已经完成了Silverlight组件的动态装配。

示例源码下载地址: MEFDemo_SL.rar

示例代码下载地址:MEFDemo_SL.rardao到

PS:下一篇将通过实例介绍MEF在Winform中实现UI的装配.