Visual Studio 2010中Silverligh实现页面动态装配

开发 后端
.NET 4.0中提供了一个MEF框架用于开发支持插件的软件系统,幸运的是,Silverlight 4也支持MEF,这就使得我们可以很容易地实现页面的动态装配功能。

.NET 4.0中提供了一个MEF框架用于开发支持插件的软件系统,幸运的是,Silverlight 4也支持MEF,这就使得我们可以很容易地实现页面的动态装配功能。

用户在访问Silverlight应用程序时,开始可以只显示一个“初始的简单的”页面,当用户需要时,动态从Web网站上下载新的程序集,然后,Silverlight客户端应用程序再使用MEF将动态下载的程序集中所包容的页面组件“组装”为一个新的功能增强了的页面,示例解决方案DynamicComposePage展示了相关的技术细节。下面简要介绍一下其开发步骤。

1 使用Visual Studio 2010创建一个名为DynamicComposePage的Silverlight Business Application项目,Visual Studio 2010将会帮助我们创建一个名为DynamicComposePage.Web的ASP.NET网站,它引用名为DynamicComposePage的Silverlight项目。

在解决方案资源管理器中展开DynamicComposePage项目节点,在其Views文件夹下可以看到Visual Studio 2010生成的一个Home.xaml页面,等一会我们将修改此页面实现页面的动态装配。

2 现在需要提供一个MEF部件都遵循的接口,为此,向解决方案中添加一个“Silverlight类库(Silverlight Class Library)”项目[1]MyPartContract,并向其中添加一个IMyPart接口,为简单起见,本例不为此接口添加任何成员,当然,在实际开发中可以依据需要为其添加合适的成员。

  1. namespace MyPartContract  
  2.  
  3. {  
  4.  
  5. public interface IMyPart  
  6.  
  7. {  
  8.  
  9. }  
  10.  

注意:这不是普通的“类库”项目,Silverlight所使用的程序集是重新编写的,与标准的.NET Framework不一样。

3 下面定义可供动态组合的Silverlight页面组件。

向示例解决方案中添加一个名为“MyPageParts”的“Silverlight类库(Silverlight Class Library)”项目,注意在弹出的对话框中选择“Silverlight 4”。然后,向MyPageParts项目中添加一个“Silverlight User Control”,取名“MyEditorControl”,在这个页面中我们将放置一个RichTextArea控件充当文字编辑器:

  1. <UserControl x:Class="MyPageParts.MyEditor" ……> 
  2. <RichTextArea x:Name="MyEditorControl" …… /> 
  3. </UserControl> 

现在,需要让此用户控件可以被MEF动态装配,为此,需要完成两个步骤:

(1)给本项目(也包括前面创建的Silverlight项目DynamicComposePage)都添加对包容了IMyPart接口的Silverlight类库MyPartContract的引用。

(2)给本项目(也包括前面创建的Silverlight项目DynamicComposePage)都添加对MEF核心程序集System.ComponentModel.Composition.dll的引用,将要负责完成“装配”工作的Silverligh项目DynamicComposePage还需要添加对另一个核心程序集System.ComponentModel.Composition.Initialization.dll的引用。注意:在以下位置才能找到上述程序集:C:\Program Files\Microsoft SDKs\Silverlight\v4.0\Libraries。下面是支持MEF动态装配的Silverlight 4用户控件的相应代码,注意其中的“[Export]”标记:

Silverlight 4用户控件

  1. [Export(typeof(IMyPart))]   
  2. public partial class MyEditor : UserControl,IMyPart  
  3.  
  4. {  
  5.  
  6. public MyEditor()  
  7.  
  8. {  
  9.  
  10. InitializeComponent();  
  11.  
  12. }  
  13.  

4 现在开发进行“动态装配”的Silverlight页面(位于DynamicComposePage项目Views文件夹中的Home.xaml),在页面上放置一个Button用于启动装配过程,另一个TextBlock用于显示提示信息,更重要地,放置一个ContentControl作为部件容器,用于显示动态装配出来的页面部件:

  1. <StackPanel> 
  2. <Grid x:Name="LayoutRoot"> 
  3. ……  
  4. </Grid> 
  5. <Button x:Name="btnShowEditor"   
  6. Click="btnShowEditor_Click" ……/> 
  7. <TextBlock x:Name="txtInfo" ……/> 
  8. <ContentControl x:Name="MyEditorContainer"/>   
  9. </StackPanel> 

#p#
下面简介一下此页面中的关键代码,首先,我们需要指定Home.xaml页面“需要”一个IMyPart部件,为此,我们给Home类添加以下属性,并且给其附加“[Import]”标记:

  1. [Import(typeof(IMyPart))]   
  2. public IMyPart mypart { get; set; } 

在Home.xaml页面初次显示时,并不加载部件程序集,当用户点击按“我要编辑文本”按钮后,动态创建一个WebClient对象从Web网站上下载程序集:

  1. private void DownloadAssemblyAndCompose()  
  2.  
  3. {  
  4.  
  5. //获取程序集的URI  
  6. string uri = Application.Current.Host.Source.AbsoluteUri;  
  7. int index = uri.IndexOf("/ClientBin"); //找出根URL  
  8. uriuri = uri.Substring(0, index) + "/MyParts/MyPageParts.dll";  
  9. WebClient client = new WebClient();  
  10. this.txtInfo.Text = "正在下载文本编辑器组件……";  
  11. client.OpenReadCompleted += new   
  12. OpenReadCompletedEventHandler(client_OpenReadCompleted);  
  13. //启动异步下载  
  14. client.OpenReadAsync(new Uri(uri));  
  15. this.btnShowEditor.IsEnabled = false; //防止用户第二次启动下载……  
  16.  

注意:在本示例中我们假设所有的可装配部件都放在Web网站的MyParts文件夹下,并且假设我们已经知道了要下载的程序集文件名。在实际项目中,我们可以设计一个用于扫描部件文件夹并向Silverlight客户端返回可装配部件的WCF Service,以允许真正“全动态”的装配工作。上述代码为WebClient的下载完毕事件(OpenReadCompletedEvent)挂接了一个事件响应方法,其中包容了本例最核心的功能代码:

  1. void client_OpenReadCompleted(object sender,   
  2. OpenReadCompletedEventArgs e)  
  3.  
  4. {  
  5. //加载资源  
  6. AssemblyPart part = new AssemblyPart();  
  7. Assembly ass = part.Load(e.Result); //提取程序集  
  8. //创建Catalog  
  9. AssemblyCatalog cata = new AssemblyCatalog(ass);  
  10. CompositionContainer container = new CompositionContainer(cata);  
  11. CompositionBatch bat = new CompositionBatch();  
  12. bat.AddPart(this);  
  13. container.Compose(bat); //装配……  
  14. //显示装配好的页面组件  
  15. if (mypart != null)  
  16. MyEditorContainer.Content = mypart;  
  17.  

上述代码中的关键在于下载程序集完成之后,从流中动态加载程序集,然后再调用MEF来装配部件。

5 最后一步,在Web网站中创建一个专用的部件文件夹“MyParts”,将包容了可装配部件的程序集复制到这一文件夹下。

创建MyParts文件夹

下图展示了示例项目运行时动态下载并组装页面的截图:

项目运行时动态

从本示例看到,将MEF和WebClient组件结合起来,可以让我们实现Silverlight页面的“按需下载”和“动态组合”,充分展示了Silverlight 4的强大功能!

【编辑推荐】

  1. Visual Studio 2010中Parallel类实现并行计算
  2. Visual Studio 2010中C++项目升级指南
  3. Visual Studio 2010中测试用例工作项类型介绍
  4. 在Visual Studio 2010选择合适的项目测试方法
  5. 细数VS 2003到Visual Studio 2010的开发之路
责任编辑:王晓东 来源: 博客园
相关推荐

2010-01-28 09:07:50

Visual Stud

2009-08-21 13:29:20

Visual Stud

2009-12-02 09:43:38

Visual Stud

2010-03-11 15:23:44

Visual Stud

2009-11-10 13:43:37

Visual Stud

2010-09-25 08:50:00

Visual Stud

2009-07-02 10:07:24

C# 4.0的动态类型Visual Stud

2009-09-07 09:22:17

Visual Stud代码片段

2010-05-14 15:05:38

Visual Stud

2010-07-20 08:43:00

Visual Stud

2009-11-24 09:00:02

Visual Stud

2010-07-15 08:50:09

SharePointVisual Stud

2010-03-19 13:17:26

Parallel

2010-03-19 16:43:37

Visual Stud

2010-02-22 16:43:33

Visual Stud

2009-11-11 09:48:06

Visual Stud

2009-09-02 16:21:17

Visual BasiC#语言

2012-09-19 10:14:12

Visual Stud

2010-04-15 08:40:00

UML建模Visual Stud

2010-03-10 09:28:58

Visual Stud
点赞
收藏

51CTO技术栈公众号