一起谈.NET技术,Silverlight开发廋身攻略(二)

  继上一篇《Silverlight开发廋身攻略(一)》,在上一节中我主要介绍了在实际开发中怎么动态加载图片资源的方法,并附有实例。在这一节中主要给大家介绍MEF(Managed Extensibility Framework)的知识来实现Xap包的动态加载。

  Managed Extensibility Framework(MEF)是.NET平台下的一个扩展性管理框架,它是一系列特性的集合,包括依赖注入(DI)以及Duck Typing等。MEF为开发人员提供了一个工具,让我们可以轻松的对应用程序进行扩展并且对已有的代码产生最小的影响,开发人员在开发过程中根据功能要求定义一些扩展点,之后扩展人员就可以使用这些扩展点与应用程序交互;同时MEF让应用程序与扩展程序之间不产生直接的依赖,这样也允许在多个具有同样的扩展需求之间共享扩展程序。简单的说:MEF程序设计主要Export (输出)、Import (输入)、Compose (组合)三个动作来完成。MEF的核心包括一个catalog和一个CompositionContainer。category用于发现扩展,而container用于协调创建和梳理依赖性。每个可组合的Part提供了一个或多个Export,并且通常依赖于一个或多个外部提供的服务或Import。每个Part管理一个实例为应用程序运行。
  关于MEF的基础知识在这里不是重点,大家可以在网上搜一下,有很多介绍这方面的文章。下面直截以实例转入正题。在实例中我们创建三个Silverlight Application项目,它们分别是:MEFLoadXap、FristXap、SecondXap。MEFLoadXap是主项目,它是一个容器,通过它来动态加载FristXap、SecondXap包。本实例环境是VS.net 2010 net4.0,在Net4.0中集成了MEF的功能。

  一、新建MEFLoadXap项目

      1、用VS.net 2010新建名为MEFLoadXap的Silverlight Application项目,添加System.ComponentModel.Composition、System.ComponentModel.Composition.Initialization引用,如下图所示:    

  2、在MEFLoadXap项目下添加DeploymentCatalogService.cs文件,在文件中添加IDeploymentCatalogService接口,并编写继承此接口的DeploymentCatalogService的类,此类主要封装了下载指定Xap包,自动导入带有Export属性标签类型为UserControl控件对象。

  IDeploymentCatalogService代码:


/// <summary>
/// 加载Xap服务接口
/// </summary>
public interface IDeploymentCatalogService
{
/// <summary>
/// 加载Xap包的方法
/// </summary>
/// <param name="uri">Xap包路径</param>
/// <param name="completedAction">加载完成后的事件</param>
void AddXap(string uri, Action<AsyncCompletedEventArgs> completedAction = null);
/// <summary>
/// 移除Xap包的方法
/// </summary>
/// <param name="uri">Xap包路径</param>
void RemoveXap(string uri);
}

  DeploymentCatalogService类的代码:


/// <summary>
/// 加载Xap服务类
/// </summary>
[Export(typeof(IDeploymentCatalogService))]
public class DeploymentCatalogService : IDeploymentCatalogService
{
private static AggregateCatalog _aggregateCatalog;
Dictionary<string, DeploymentCatalog> _catalogs;

public DeploymentCatalogService()
{
_catalogs = new Dictionary<string, DeploymentCatalog>();
}
/// <summary>
/// 初始化对象的静态方法
/// </summary>

public static void Initialize()
{
_aggregateCatalog = new AggregateCatalog();
_aggregateCatalog.Catalogs.Add(new DeploymentCatalog());
CompositionHost.Initialize(_aggregateCatalog);
}
/// <summary>
/// 加载Xap包的方法
/// </summary>
/// <param name="uri">Xap包路径</param>
/// <param name="completedAction">加载完成后的事件</param>

public void AddXap(string uri, Action<AsyncCompletedEventArgs> completedAction = null)
{
DeploymentCatalog catalog;
if (!_catalogs.TryGetValue(uri, out catalog))
{
catalog = new DeploymentCatalog(uri);

if (completedAction != null)
{
catalog.DownloadCompleted += (s, e) => completedAction(e);
}
else
{
catalog.DownloadCompleted += catalog_DownloadCompleted;
}

catalog.DownloadAsync();
_catalogs[uri] = catalog;
_aggregateCatalog.Catalogs.Add(catalog);
}
}

void catalog_DownloadCompleted(object sender, AsyncCompletedEventArgs e)
{
if (e.Error != null)
{
throw e.Error;
}
}
/// <summary>
/// 移除Xap包的方法
/// </summary>
/// <param name="uri">Xap包路径</param>

public void RemoveXap(string uri)
{
DeploymentCatalog catalog;
if (_catalogs.TryGetValue(uri, out catalog))
{
_aggregateCatalog.Catalogs.Remove(catalog);
_catalogs.Remove(uri);
}
}
}

3、修改设计MainPage,在MainPage界面设计中我们把整个界面分为左、右两部分,左边放两个按钮,右边放一个容器控件用于承载显示动态下载Xap包中的控件,其Xaml代码如下:


<Grid x:Name="LayoutRoot" Background="#FFD8D8D8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Button Height="36" Width="160" Margin="20,106,20,158" Content="加载一" Click="Button_Click"></Button>
<Button Height="36" Width="160" Margin="20,189,20,75" Content="加载二" Click="Button_Click_1"></Button>
<Border x:Name="parentContent" Grid.Column="1"></Border>
</Grid>

  MainPage类的CS代码:


public partial class MainPage : UserControl, IPartImportsSatisfiedNotification
{
public MainPage()
{
InitializeComponent();
//通过此方法调用DeploymentCatalogService对象
//自动将此对象与CatalogService属性邦定在一起
CompositionInitializer.SatisfyImports(this);
this.Loaded += new RoutedEventHandler(MainPage_Loaded);
}

void MainPage_Loaded(object sender, RoutedEventArgs e)
{
LoadSelectedModule();
}
private string m_xapName = "FristXap.xap";

#region IPartImportsSatisfiedNotification Members

public void OnImportsSatisfied()
{
LoadSelectedModule();
}

#endregion
/// <summary>
/// 导入类型是IDeploymentCatalogService并带有Export属性标签对象
/// </summary>
[Import]
public IDeploymentCatalogService CatalogService { get; set; }
/// <summary>
/// 导入类型是UserContronl并带有Export属性标签的所有控件
/// </summary>
[ImportMany(AllowRecomposition = true)]
public Lazy<UserControl>[] mefModules { get; set; }

/// <summary>
/// 加载XAP包的方法
/// </summary>
private void LoadSelectedModule()
{
string selectXapName = m_xapName.Replace(".xap", ".");

CatalogService.AddXap(m_xapName);
var ctrs = (from m in mefModules.ToList()
where m.Value.ToString().Contains(selectXapName)
select m).FirstOrDefault();
if (ctrs != null)
{
parentContent.Child = ctrs.Value;
}

}

private void Button_Click(object sender, RoutedEventArgs e)
{
m_xapName = "FristXap.xap";
LoadSelectedModule();
}

private void Button_Click_1(object sender, RoutedEventArgs e)
{
m_xapName = "SecondXap.xap";
LoadSelectedModule();
}
}

  二、新建FristXap项目

  1、用VS.net 2010新建名为FristXap的Silverlight Application项目,添加System.ComponentModel.Composition、System.ComponentModel.Composition.Initialization引用

  2、删除FristXap项目下的App.xaml、MainPage.xaml文件,因它是被加载项目基本没有什么用处

  3、添加名为Ellipse.xaml用户控件,此控件主要作用是画一个椭圆。此控件效果图如下:    

    控件Xaml代码如下:


<Grid x:Name="LayoutRoot" >
<Ellipse Height="300" Width="400" Fill="#FF3BC73B"></Ellipse>
<TextBlock Text="第一个XAP包中的椭圆控件" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="14"></TextBlock>
</Grid>

  三、新建SecondXap项目

  1、用VS.net 2010新建名为SecondXap的Silverlight Application项目,添加System.ComponentModel.Composition、System.ComponentModel.Composition.Initialization引用

  2、删除SecondXap项目下的App.xaml、MainPage.xaml文件 

  3、添加名为Rectangle.xaml用户控件,此控件主要作用是画一个矩形。此控件效果图如下:    

  四、编译运行项目,点击如下图所示的按钮动态加载FristXap.xap、SecondXap.xap包中的控件对象,加载过程是首先判断指定的包是否已下载到本地,如果在本地则直接加载;如果不在本地,则先到远程服务器上下载Xap包,后加载控件对象。运行效果图如下:   

  本实例源代码:下载

时间: 2024-09-14 06:05:59

一起谈.NET技术,Silverlight开发廋身攻略(二)的相关文章

一起谈.NET技术,Silverlight开发廋身攻略(一)

相信大家在用Silverlight做应用开发时,随着项目的进展系统功能越来越多,肯定为Xap包越来越大而烦恼,Xap包的大小直接影响应用程序的加载速度,给用户造成不良的用户体验.我也曾为这个问题头痛过,经过在网上查阅资料和项目实践发现可通过以下三种方式给Silverlight应用程廋身. 1.定期检查系统项目模块的引用集,移除多余的引用库 2.图片资源文件,如果不是必须放在资源中的,可以采用按需加载 3.将系统划分成多个Silverlight项目,然后根据需要进行Xap加载 下面我将结合实例来对

Silverlight开发廋身攻略(“.NET研究”一)

相信大家在用Silverlight做应用开发时,随着项目的进展系统功能越来越多,肯定为Xap包越来越大而烦恼,Xap包的大小直接影响应用程序的加载速度,给用户造成不良的用户体验.我也曾为这个问题头痛过,经过在网上查阅资料和项目实践发现可通过以下三种方式给Silverlight应用程廋身. 1.定期检查系统项目模块的引用集,移除多余的引用库 2.图片资源文件,如果不是必须放在资源中的,可以采用按需加载 3.将系统划分成多个Silverlight项目,然后根据需要进行Xap加载 下面我将结合实例来对

Silverli“.NET研究”ght开发廋身攻略(二)

继上一篇<Silverlight开发廋身攻略(一)>,在上一节中我主要介绍了在实际开发中怎么动态加载图片资源的方法,并附有实例.在这一节中主要给大家介绍MEF(Managed Extensibility Framework)的知识来实现Xap包的动态加载. Managed Extensibility Framework(MEF)是.NET平台下的一个扩展性管理框架,它是一系列特性的集合,包括依赖注入(DI)以及Duck Typing等.MEF为开发人员提供了一个工具,让我们可以轻松的对应用程序

Silverlight开发身攻略(二)

继上一篇<Silverlight开发身攻略(一)>,在上一节中我主要介绍了在实际开发中怎么动态加载图片资源的方法,并附有实例.在这一节中主要给大家介绍MEF(Managed Extensibility Framework)的知识来实现Xap包的动态加载. Managed Extensibility Framework(MEF)是.NET平台下的一个扩展性管理框架,它是一系列特性的集合,包括依赖注入(DI)以及Duck Typing等.MEF为开发人员提供了一个工具,让我们可以轻松的对应用程序进

一起谈.NET技术,.Net4.0 Parallel编程(二)Data Parallelism 中

在上篇文章中看过了使用Parrallel.For.Parael.Foreach在效率上给我们带来的提高.本文就来如何终止循环.线程局部变量 进行说明. Thread-Local Variables 首先我们来看下线程局部变量,是的我们也许一直在想我们如何去定义一个线程局部变量呢.先看段顺序执行的代码: [TestMethod()]public void NormalSequenceTest(){int[] nums = Enumerable.Range(0, 1000000).ToArray()

一起谈.NET技术,ASP.NET Process Model之二:ASP.NET Http Runtime Pipeline[下篇]

ASP.NET Process Model索引 ASP.NET Process Model之一:IIS 和 ASP.NET ISAPI ASP.NET Process Model之二:ASP.NET Http Runtime Pipeline[上篇] ASP.NET Process Model之二:ASP.NET Http Runtime Pipeline[下篇] 二.ASP.NET Runtime Pipeline 现在我们真正进入ASP.NET管辖的范畴,下图基本上囊括整个处理过程涉及的对象

Win 7系统安全优化、瘦身攻略

  首先 开启 Administrator 用户 删除其他用户!~~这个应该都会吧!~~ 1."以管理员身份运行,所有程序→附件→命令提示符",右击选择"以管理员身份运行", 进入命令提示符后,手工输入"powercfg -h off" 这是干什么的,木星人也会知道-- 2.关闭系统保护 计算机右键属性--高级管理设置--系统保护 3.转移虚拟内存 计算机右键属性--高级管理设置--高级--性能-设置-高级-更改 4.转移"用户的文件&

搜索引擎优化之链接广泛度(Link Popularity)全攻略(二)-搜索引擎技术

对链接分析的一点补充友情链接/互惠链接友情链接的对象:怎样才能找到那些和你网站内容相似并且公认质量较好的网站呢?究竟什么样的页面对搜索引擎来说是有分量的?--再没有比搜索引擎更能知道这个答案的了.用你网站上最最重要的关键词(就是你最想被访问者找到的那个搜索词)在那些主要的搜索引擎上进行搜索.在搜索结果的前两到三页列出的就是搜索引擎认为与你键入关键词最相关,同时又是最流行的一些网站.而且,由于这些页面拥有很高的排名,所以一般访问量也很大.如此一来,如果你能让这些页面链向你的站点,不但能使你的广泛度

一起谈.NET技术,案例分析:Silverlight在中国人寿的应用

笔者自2003年首次听到Macromedia公司提起RIA(富互联网应用)一词到现在整整7年了.一度被认为是互联网应用趋势的RIA经历了7年之痒,但仍然没有在互联网上得到大规模普及,特别是企业应用就更加少见.做个不恰当的比喻,传统基于Html的应用就像互联网应用中的绿叶一样,而RIA技术由于酷炫的用户体验效果就像是美丽的花朵.现在开心网和腾讯QQ等商业应用中已经运用了RIA技术在其社交网站中得到应用,但这毕竟还是少数,大多数互联网应用特别是企业级应用仍然选择传统高稳定性与高响应能力的Html应用