设为首页 收藏本站
查看: 1088|回复: 0

Windows phone 应用开发[7]-MEF For Windows phone

[复制链接]

尚未签到

发表于 2015-5-8 10:58:02 | 显示全部楼层 |阅读模式
  本篇是接着上篇Windows phone 应用开发[6]-Managed Extensibility Framework应用程序扩展 基础之上而来. 关于Managed Extensibility FrameWork[MEf]基础概念这里不再赘述.MEF 作为.NET 4一部分.同时也支持Silverlight4 版本.但因目前官方并没有推出Managed Extensibility Framework For Windows phone 版本. 对Codeplexhttp://mef.codeplex.com/上类库并不支持Windows phone. 这里介绍另外一种方式在Windows phone 中使用MEF.并以一个简单实例 抛砖引玉.
  在开始介绍之前如果你对MEf For Windows phone 中使用存在问题和相关的技术瓶颈 想了解一番可以阅读如下文章:
  
  MEf For Windows phone By damonpayne:
  http://www.damonpayne.com/post/2010/06/25/MEF-for-Windows-Phone-7.aspx
  
  这篇文章中作者Damonpayne很详细阐述了MEF 发展的过程以及相对Windows phone 开发不支持的一些相关特性类似:System.Reflection.Emit剔除. 针对MEF操作同样也不支持IQueryable接口的类Linq操作等.并提出自己的一套在Windows phone 中使用MEF的解决方案.可惜的是作者直接给一个封装不完整DLL.并删除下载页面.经过实际代码尝试Damonpayne给出的一条DeadWay.
  而欣慰的总是有人在无意间给你额外的惊喜. 在我看Microsoft Silverlight Analytics Framework[MSAF]源码时意外的发现.这个开源框架中尽然移植一个Windows phone 版本的MEF:
DSC0000.png
  MSAF分别针对原ComponentModel和Composition.Initialization空间做了Windows phone 类库的移植. 而如上类库正是MEF的核心.MSAF框架主要作用是提供了一种标准方法在Windows phone应用程序中添加对使用情况加以跟踪并支持第三方数据分析的功能.这个我会下篇中Windows phone采集用户数据和行为分析上讲解.
  Well 似乎MEF支持问题就如此意外的迎刃而解了.如下来做一个简单实例来验证.现在提出一个简单需求我们宿主程序中要通过MEF方式集成一个管理分类的组件.组件和Windows phone宿主程序关系如下:
DSC0001.png
  以创建一个Windows phone的类库形式来实现这个组件 创建类库并命名-MEFCommon.Data.首先添加MEF 类库的引用:
DSC0002.png
  分别引用了元MSAF源码中System.ComponentModel和Composition.Initialization两个DLL.创建一个封装组件分类操作的接口IAppCatalog 添加引用如下:
  
      1:  using System.ComponentModel;
   2:  using System.ComponentModel.Composition;
   3:  using System.ComponentModel.Composition.Hosting;
  接口中分别定义两个操作方法.一个用来添加分类方法 另外一个获取所有分类的数据方法:



   1:     public interface IAppCatalog
   2:      {
   3:         bool AddCatalog(AppCatalog newAppCatalog);
   4:         List GetAllAppCatalogList();
   5:      }
  创建AppCatalogOperator类实现该接口:



   1:      [Export(typeof(IAppCatalog))]
   2:      public class AppCatalogOperator:IAppCatalog
   3:      {
   4:          public List OperatorCatalogList = new List();
   5:   
   6:          public bool AddCatalog(AppCatalog newAppCatalog)
   7:          {
   8:              //No Check Reply
   9:              if(newAppCatalog!=null)
  10:                 this.OperatorCatalogList.Add(newAppCatalog);
  11:              return true;
  12:          }
  13:   
  14:          public List GetAllAppCatalogList()
  15:          {
  16:              this.OperatorCatalogList.Clear();
  17:              this.OperatorCatalogList.Add(new AppCatalog() { CatalogName = "Music+Video", CatalogNote = "Important for Common User" });
  18:              this.OperatorCatalogList.Add(new AppCatalog() { CatalogName = "Game", CatalogNote = "Different Kind of Game platform" });
  19:              this.OperatorCatalogList.Add(new AppCatalog() { CatalogName = "Book", CatalogNote = "Reader" });
  20:   
  21:              return this.OperatorCatalogList;
  22:   
  23:          }
  24:      }
  同时在该类以IAppCatalog接口作为契约名向MEF开放.该类一方面提供分类的全部数据同时能够执行添加分类的操作.如下我们要在一个Windows phone宿主程序中用到分类组件提供分类数据.绑定UI上显示,定义一个UI上可操作的ViewModel:



   1:      public class AppCatalog_ViewModel:BasicViewModel
   2:      {
   3:          public AppCatalog_ViewModel()
   4:          {
   5:              CompositionInitializer.SatisfyImports(this);
   6:          }
   7:   
   8:          public ObservableCollection appCatalogCollection = new ObservableCollection();
   9:          public ObservableCollection AppCatalogCollection
  10:          {
  11:              get { return this.appCatalogCollection; }
  12:              set
  13:              {
  14:                  this.appCatalogCollection = value;
  15:                  base.NotifyPropertyChangedEventHandler("AppCatalogCollection");
  16:              }
  17:          }
  18:   
  19:          [Import(typeof(IAppCatalog))]
  20:          public IAppCatalog CurrentCatalogData { get; set; }
  21:   
  22:          public void LoadAppCatalogData()
  23:          {
  24:              if (this.CurrentCatalogData != null)
  25:              {
  26:                  if (this.CurrentCatalogData.GetAllAppCatalogList().Count > 0)
  27:                  {
  28:                      var catalogList = this.CurrentCatalogData.GetAllAppCatalogList();
  29:                      this.appCatalogCollection.Clear();
  30:                      catalogList.ForEach(x => { this.appCatalogCollection.Add(x); });
  31:                  }
  32:              }
  33:          }
  34:      }
  首先在ViewModel定义一个以Import标识IAppcatalog类型属性用来接收组件中通过MEF需要传递的数据.其实这就是宿主程序一个扩展点.同样这个Windows phone宿主程序需要添加对组件类库和MEF 引用.现在有了组件的数据 和宿主程序的扩展点接入.Well,要实现组件与宿主程序之间通信则需要通过MEF建立组合的关联关系. 而这个组合关系引用需要在应用程序启动是调用.上篇中我们采用是一个Console应用程序直接写在Main方法.作为Windows phone当然也可以直接写在Launching和Activated事件中.当然最好的方式是创建一个实现IApplicationService接口的应用程序服务.可以获得更好的代码封装和关注分离的效果 创建Service如下:



   1:      public class MEFAppCatalogService:IApplicationService
   2:      {
   3:          public MEFAppCatalogService()
   4:          {
   5:              CompositionHost.Initialize
   6:                  (new AssemblyCatalog(Application.Current.GetType().Assembly),
   7:                   new AssemblyCatalog(typeof(MEFCommon.Data.IAppCatalog).Assembly));
   8:          }
   9:   
  10:          public void StartService(ApplicationServiceContext context) {   }
  11:   
  12:          public void StopService() {  }
  13:      }
  在构造方法中.调用CompositionHost对象Initialize()方法.相对于上篇我们直接通过定义CompositionContainer容器的方式.而目前CompositionHost对象提供用于控制 CompositionInitializer 所使用的容器的静态方法.二者效果是一致的. Initialize()方法在构造是可以接受任意数量的目录. 这和AggregateCatalog对象指定MEF解析范围是一致的.目录适用于定义MEF在解析类型是需要检索的位置范围.而引用的对象AssemblyCatalog则分别提供对分类组件类库和宿主应用程序的静态引用.
  接着指定运行的位置.向App.xaml内Application.ApplicationLifetimeObjects集合添加一个MEFAppCatalogService实例.则宿主程序会在任何应用程序代码运行之前调用服务的Initialize方法来初始化MEF的管理容器.



   1:      
   2:         
   3:         
   6:         
   7:         
   8:      
  最后就是通过在ViewModel够着方法中调用CompositionInitializer对象的SatisfyImports()方法实现填充指定组件的导入.[observerCollection集合已经绑定UIlistBox控件]:



   1:  //组件导入
   2:   CompositionInitializer.SatisfyImports(this);
  现在运行Windows phone应用程序看分类组件提供分类数据能拿到:
DSC0003.png
  ok.成功通过MEF框架宿主程序自动感知的灵活方式添加组件并获得组件提供分类数据.证明MASF提供MEF类库是可行的.到这了不禁有人会问相对上篇难道没有其他方式建立宿主和组件之间组合关系?答案是肯定的.
  只不过如果我们不以Service形式.我们建立组件关系.这段建立组合关系代码放在那? 应该采用什么方式来组合? 来看看Mainpage绑定ViewModel时:



   1:         //Bind ViewModel
   2:          private AppCatalog_ViewModel appcatalog_ViewModel = null;
   3:          void MainPage_Loaded(object sender, RoutedEventArgs e)
   4:          {
   5:              if (this.appcatalog_ViewModel == null)
   6:                  this.appcatalog_ViewModel = new AppCatalog_ViewModel();
   7:              this.appcatalog_ViewModel.LoadAppCatalogData();
   8:              this.DataContext = appcatalog_ViewModel;
   9:          }
  可见每次都会Load时重新构造并调用ViewModel构造方法.考虑可以把组合关系代码放在这.CompositionInitializer对象提供了对MEF容器的静态方法控制.当然我们也可以像上篇一样显示的定义一个CompositionContainer 容器的方式直接管理. 可以把原ViewModel中代码替换成:



   1:            
   2:              //显示建立关联关系
   3:              AggregateCatalog mefCatalog = new AggregateCatalog();
   4:              mefCatalog.Catalogs.Add(new AssemblyCatalog(Application.Current.GetType().Assembly));
   5:              mefCatalog.Catalogs.Add(new AssemblyCatalog(typeof(MEFCommon.Data.IAppCatalog).Assembly));
   6:   
   7:              CompositionContainer mefContainer = new CompositionContainer(mefCatalog);
   8:              mefContainer.ComposeParts(this);
  通过AggregateCAtalog显示指定MEF解析类型需要检索的位置范围。编译运行发现效果是一致的.
  关于这两种方式.最简洁使用就是CompositionInitializer对象提供静态控制.把更多的工作交给MEF自身去做. 另外一个好处就是可以随时随地在程序中添加MEF组合关系和检索位置的范围.这是显示定义CompositionContainer 容器方式所无法直接做到的.
  Well关于MEF终于历经多次验证终于能够成功运行在Windows phone应用程序中.本篇只是介绍简单使用方法.目的是抛砖引玉.体现MEF也能够在Windows phone扩展组件能力和灵活的方式都值得我们在实际项目加以实践. 算是提出MEF 在Windows phone中使用一种解决方案.如果任何问题请在评论中提出.如下会给出本篇实例源码和MASF MEF For windows phone版本的DLL.
  本篇实例代码:/Files/chenkai/MEFSampleDemo.rar
  MEF For windows Phone DLL文件:/Files/chenkai/ComponentModelDLL.rar
  参考资料:
  MEF For Windows phone 7 By DAmon Payne
  MEF Contrib [Github]
  Microsoft Silverlight Analyics FrameWork Codeplex

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-64923-1-1.html 上篇帖子: Windows Phone 7 开发向导 V2.0提供下载 下篇帖子: Windows Phone 7完整版模拟器
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表